2

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);
    }
    ...
}
HoRn
  • 1,458
  • 5
  • 20
  • 25
王江涛
  • 59
  • 4

1 Answers1

1

I found the answer myself, the KeyedPooledObjectFactory is absolutely thread-safe

HoRn
  • 1,458
  • 5
  • 20
  • 25
王江涛
  • 59
  • 4