ConcurrentHashMap实现数据库连接的线程安全问题
2018-01-15 12:41
525 查看
private ConcurrentHashMap<String,FutureTask<Connection>>connectionPool = newConcurrentHashMap<String, FutureTask<Connection>>();
public Connection getConnection(String key) throws Exception{
FutureTask<Connection>connectionTask=connectionPool.get(key);
if(connectionTask!=null){
return connectionTask.get();
}
else{
Callable<Connection> callable = new Callable<Connection>(){
@Override
public Connection call() throws Exception {
// TODO Auto-generated method stub
return createConnection();
}
};
FutureTask<Connection>newTask = new FutureTask<Connection>(callable);
connectionTask = connectionPool.putIfAbsent(key, newTask);
if(connectionTask==null){
connectionTask = newTask;
connectionTask.run();
}
return connectionTask.get();
}
}
//创建Connection
private Connection createConnection(){
return null;
}
这是在网上看到的一段 ConcurrentHashMap实现数据库连接的代码,发现有个问题:
就是在线程A、B同时执行获取数据库连接的方法时,如果线程A执行完17行,返回null,说明它是首个存入该key的线程,但是不幸的是A线程因为某些原因此时突然挂掉了。线程B执行到17行时发现此时已经有线程存入了key,connectionTask不为null,则直接跳到22行去get数据库连接,但是因为线程A没有执行完创建连接,所以线程B就一直阻塞在get方法上。请各位大神看看是不是存在这个问题,如果存在,如何更好的解决?
问题解决:在可能出现异常的地方添加一个异常捕获,如果发生异常就将之前添加的key-value删除,我理解这样就可避免线程无限阻塞的问题了,各位看看还有没有其他问题,欢迎留言
public Connection getConnection(String key) throws Exception{
FutureTask<Connection>connectionTask=connectionPool.get(key);
if(connectionTask!=null){
return connectionTask.get();
}
else{
Callable<Connection> callable = new Callable<Connection>(){
@Override
public Connection call() throws Exception {
// TODO Auto-generated method stub
return createConnection();
}
};
FutureTask<Connection>newTask = new FutureTask<Connection>(callable);
connectionTask = connectionPool.putIfAbsent(key, newTask);
if(connectionTask==null){
connectionTask = newTask;
connectionTask.run();
}
return connectionTask.get();
}
}
//创建Connection
private Connection createConnection(){
return null;
}
这是在网上看到的一段 ConcurrentHashMap实现数据库连接的代码,发现有个问题:
就是在线程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();
相关文章推荐
- Android下数据库线程安全问题
- [转]在Java中实现.net中DataTable功能以及操作双数据库的List连接问题解决方案探究
- Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题
- JAVA基础再回首(二十四)——多线程的概述、实现方式、线程控制、生命周期、多线程程序练习、安全问题的解决
- Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题
- 一个简单的Java对象池实现——可用来解决SimpleDateFormat的线程安全问题
- Java 数据库连接安全关闭代码实现
- Spring 数据库连接(Connection)绑定线程(Thread)的实现
- Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题
- Linux下C/C++连接MySQL之线程安全问题
- Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题
- 多线程简单实现与线程安全问题的简单处理
- Hashtable、HashMap、ConcurrentHashMap 底层实现原理与线程安全问题
- Hashtable、HashMap、ConcurrentHashMap底层实现原理与线程安全问题
- treeview问题.每个结点包含多个值的实现。(添加、删除、拖拉、连接数据库等
- Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题
- 利用JAVA线程安全队列简单实现读者写者问题。
- Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题
- 0019 Servlet容器的实现:单实例多线程的线程安全问题【基础】
- Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题