首页 > 解决方案 > Is GenericObjectPools method thread safe?

问题描述

I read article of Is GenericObjectPools borrowObject Method thread safe?. I'm getting the same issue with this, my code is:

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()));
    }

As he said constructor is un-thread-safe. As far as I know, the methods are invoked in the thread-safe stack, but why did he say the constructor in his demo is unsafe?

The problem I'm facing is that when borrow object getting the same Connection. Here is my code:

@Component
public class HsmConnectionManager {
    
    private static final Logger logger = LoggerFactory.getLogger(HsmConnectionManager.class);
    
    @Resource
    private GenericKeyedObjectPool<ThriftConfigDto, TProtocol> keyedObjectPool;
    public ConnectionDto getConnection(ThriftConfigDto dto) throws BusinessException {
        if (dto == null) {
            throw new BusinessException(EnumErrorCode.SYS_HSM_CONNECTION_ERR);
        }
        Assert.notNull(dto.getIp(), "Thrift ip can not be null.");
        Assert.notNull(dto.getPort(), "Thrift port can not be null.");
        
        try {
            TProtocol protocol = keyedObjectPool.borrowObject(dto);
            CVService.Iface client = new CVService.Client(protocol);
            return new ConnectionDto(dto, protocol, client);
        } catch (Exception e) {
            logger.error(e.getMessage());
            logger.error("com.safevast.hsm.factory -> getConnection::ThriftConfigDto = [{}]", dto);
            throw new BusinessException(EnumErrorCode.SYS_HSM_CONNECTION_ERR, e);
        }
    }
}

@Component
public class HsmProtocolFactory implements KeyedPooledObjectFactory<ThriftConfigDto, TProtocol> {
    @Override
    public PooledObject<TProtocol> makeObject(ThriftConfigDto key) throws Exception {
    
        TSocket socket = new TSocket(key.getIp(), key.getPort(), key.getMaxWait().intValue());
        socket.open();
        TProtocol protocol = new TBinaryProtocol(socket);
    
        logger.debug("com.safevast.hsm.factory -> makeObject::IP = [{}], PORT = [{}]", key.getIp(), key.getPort());
        return new DefaultPooledObject<>(protocol);
    }
    ...
}

标签: java

解决方案


我自己找到了答案,KeyedPooledObjectFactory绝对是线程安全的


推荐阅读