ConcurrentHashMap实现数据库连接的线程安全问题

  1. private ConcurrentHashMap<String,FutureTask<Connection>>connectionPool = newConcurrentHashMap<String, FutureTask<Connection>>();
  2. public Connection getConnection(String key) throws Exception{
  3. FutureTask<Connection>connectionTask=connectionPool.get(key);
  4. if(connectionTask!=null){
  5. return connectionTask.get();
  6. }
  7. else{
  8. Callable<Connection> callable = new Callable<Connection>(){
  9. @Override
  10. public Connection call() throws Exception {
  11. // TODO Auto-generated method stub
  12. return createConnection();
  13. }
  14. };
  15. FutureTask<Connection>newTask = new FutureTask<Connection>(callable);
  16. connectionTask = connectionPool.putIfAbsent(key, newTask);
  17. if(connectionTask==null){
  18. connectionTask = newTask;
  19. connectionTask.run();
  20. }
  21. return connectionTask.get();
  22. }
  23. }
  24. //创建Connection
  25. private Connection createConnection(){
  26. return null;
  27. }


  1. 这是在网上看到的一段 ConcurrentHashMap实现数据库连接的代码,发现有个问题:
  2. 就是在线程A、B同时执行获取数据库连接的方法时,如果线程A执行完17行,返回null,说明它是首个存入该key的线程,但是不幸的是A线程因为某些原因此时突然挂掉了。线程B执行到17行时发现此时已经有线程存入了key,connectionTask不为null,则直接跳到22行去get数据库连接,但是因为线程A没有执行完创建连接,所以线程B就一直阻塞在get方法上。请各位大神看看是不是存在这个问题,如果存在,如何更好的解决?


问题解决:在可能出现异常的地方添加一个异常捕获,如果发生异常就将之前添加的key-value删除,我理解这样就可避免线程无限阻塞的问题了,各位看看还有没有其他问题,欢迎留言
    try {
        if (connectionFutureTask==null) {
            connectionFutureTask = newTask;
            connectionFutureTask.run();
        }
    } catch (Exception e) {
        connectionPool.remove(key, newTask);
        e.printStackTrace();
        throw new RuntimeException("connectionCreateFail!!!");
    }
    return connectionFutureTask.get();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值