2013-08-08 3 views
2

이 질문에 Is GenericObjectPool<T> from commons.apache.org thread safe? 스레드 안전성이 언급되어 있습니다.GenericObjectPool borrowObject 메소드 스레드로부터 안전합니까?

편집 :하지만 내 멀티 스레드 응용 프로그램에서 두 스레드가 같은 개체를 동시에 풀에서 가져 오는 상황이 있습니다 .-이 문은 잘못되었습니다.

블록을 동기화하기 위해 borrowObject를 이동 했으므로 문제가 해결되었습니다.

이전에이 문제에 직면 한 사람이 있습니까?

public static GenericObjectPool<IDocBuilderPool> documentBuilderPool = new GenericObjectPool(new DocumentPool()); 

static { 
    documentBuilderPool.setMaxActive(1000); 
    documentBuilderPool.setMaxWait(30000); 
    documentBuilderPool.setMaxIdle(-1); 

} 
//method that returns document pool called by multiple threads . 

public static IDocBuilderPool getDocumentPool() { 

    return documentBuilderPool.borrowObject(); 
} 

//The pool factory class 
public class DocumentPool extends BasePoolableObjectFactory<ICollabrrDocument> { 

    public DomDocumentPool() { 
    } 

    @Override 
    public DomDocument makeObject() throws Exception { 
     // TODO Auto-generated method stub 
     return new DomDocument(); 
    } 

    @Override 
    public void activateObject(IDocBuilderPool obj) throws Exception { 
     // TODO Auto-generated method stub 
     super.activateObject(obj); 
    } 

    @Override 
    public void destroyObject(IDocBuilderPool obj) throws Exception { 
     // TODO Auto-generated method stub 
     super.destroyObject(obj); 

    } 

    @Override 
    public void passivateObject(IDocBuilderPool obj) throws Exception { 
     // TODO Auto-generated method stub 
     obj.release(); 
     super.passivateObject(obj); 
    } 

    @Override 
    public boolean validateObject(IDocBuilderPool obj) { 
     // TODO Auto-generated method stub 
     return super.validateObject(obj); 
    } 
} 




public class DomDocument implements IDocBuilderPool { 

private Document domDocument; 
private DocumentBuilder documentBuilder; 
private DocumentBuilderFactory documentBuilderFactory; 

public HashMap<org.w3c.dom.Node, DOMElement> elementMap = new HashMap<org.w3c.dom.Node, DOMElement>(); 

public long threadID; 

public DomDocument() { 


    setDomDocument(); 
    this.threadID = Thread.currentThread().getId(); 

} 

public void setDomDocument() throws 
    this.documentBuilderFactory = DocumentBuilderFactory.newInstance(); 


     this.documentBuilderFactory.setNamespaceAware(true); 
     this.documentBuilder = this.documentBuilderFactory.newDocumentBuilder(); 
     this.domDocument = this.documentBuilder.parse(new ByteArrayInputStream("<Root/>".getBytes())); 


} 

}

+0

테스트를 게시하여 재현 할 수 있습니까? 코드 나 테스트의 버그 일 수 있습니다. BTW 일반 객체 풀은 Java 5.0 이후로 항상 새로운 객체를 만드는 것보다 비쌉니다. 나는 객체 풀을 사용하지만 특정 유스 케이스에 맞게 조정 된 클래스 특정 객체 풀이어야하는 것이 더 빠르다는 것을 발견했다. –

+0

클래스의 모든 public 메소드가 동기화되어 ok로 표시됩니다 (작업은 생성자에서 예약되지만 문제가되지는 않습니다). 그래서 문제는 아마도 귀하의 코드에 있습니다 ... – assylias

+0

안녕 assylias., 작업은 genericobject 풀의 퇴거 정책에 따라 예정입니다. 어떤 식 으로든 그것을 활성화하지 않았습니다. 위의 코드를 확인하십시오. –

답변

2

documentation of PoolableObjectFactory 상태 :

PoolableObjectFactory이 스레드 안전해야

여기 내 코드입니다.

코드를 살펴보면 스레드 안전하지 않은 유일한 것은 obj.release();입니다. 문제가있는 곳일 수 있습니다.

그 외에도 모두 괜찮아 보이는군요 ...

+0

obj.release()는 특정 객체에서만 작동하는 인스턴스 호출입니다. –

+1

@BijuCNair 사실 저는 당신에게 BS를주었습니다. 제가보고있는 코드는 확실하지 않지만 [이 구현 v1.6의 GenericObjectPool] (http://commons.apache.org/proper/commons-pool/api-1.6/) src-html/org/apache/commons/pool/impl/GenericObjectPool.html # line.192)은 ** 동기화되지 않았습니다 **. 특히, 새로운 객체를 반환하는'borrowObject' 메소드 (라인 1058)는 복잡한 동기화를 사용하며, 그것이 정확한지 한 눈에 말하기는 어렵습니다. 버그가있을 수 있습니다 (모르겠습니다). – assylias