锁定老帖子 主题:一个关于连接池很基础的讨论.
精华帖 (1) :: 良好帖 (0) :: 新手帖 (19) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-02-18
je回复这么垃圾吗,什么双重检测都出来了,我来告诉LZ可以要也可以不要,如果业务中要只调用getDataSource方法你说要不要呢,所以按照junit 的流程应该要
|
|
返回顶楼 | |
发表时间:2011-02-18
在并发情况下,如果不加锁,datasource初始化阶段可能产生多个datasource实例,但是你的全局量最终只会使用一个,而多的几个就被分配个其他的并发线程了,这样就不能严格保证实例的唯一性,这就是单例模式的问题!
加了锁的这个类方法,肯定会产生线程排队问题,而且如此基础的类,一定会极大的产生性能影响! 建议,在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁! |
|
返回顶楼 | |
发表时间:2011-02-18
fangshun 写道 在并发情况下,如果不加锁,datasource初始化阶段可能产生多个datasource实例,但是你的全局量最终只会使用一个,而多的几个就被分配个其他的并发线程了,这样就不能严格保证实例的唯一性,这就是单例模式的问题!
加了锁的这个类方法,肯定会产生线程排队问题,而且如此基础的类,一定会极大的产生性能影响! 建议,在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁! 那么多回复,终于见到一个好使的。 |
|
返回顶楼 | |
发表时间:2011-02-18
fangshun 写道 在并发情况下,如果不加锁,datasource初始化阶段可能产生多个datasource实例,但是你的全局量最终只会使用一个,而多的几个就被分配个其他的并发线程了,这样就不能严格保证实例的唯一性,这就是单例模式的问题!
加了锁的这个类方法,肯定会产生线程排队问题,而且如此基础的类,一定会极大的产生性能影响! 建议,在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁! 是单例的问题。采用 内部类进行延迟加载 也可以避免对类方法的锁。。。可以看看 研读设计模式 里面关于单例的讲解,非常清晰。 |
|
返回顶楼 | |
发表时间:2011-02-18
首先这段代码设计的不好。有种乱七八糟的感觉,看起来写代码的人想延迟加载,但是表现的有点模糊。
实际上加第一句的好处在于节省效率,只要datasouce已经初始化过了,就不再理会初始化的问题。因为初始化涉及到一个锁,所以效率的提升在这一句应该比较大。 跟多重检查也没关系。 |
|
返回顶楼 | |
发表时间:2011-02-18
rong889 写道 假设刚开始datasource为null,这时候有10个线程同时访问getConnection(),同时执行到
# if (datasource == null) { # getDataSource(); # } 那么getDataSource()会被调用10次,如果getDataSource()中不加if (datasource == null),datasource 就会被初始化10次。 因此加上还是有必要的,能够避免datasource被重复初始化。 赞同 rong889 的说法。 第一个null判断是为了提高效率,第二个是为了保证datasource的唯一性。 |
|
返回顶楼 | |
发表时间:2011-02-18
最后修改:2011-02-18
class A { private static DataSource datasource = null; private static Object syncObj = new Object(); // you can use another way to sync private static Connection getConnection() { if (datasource == null) { synchronized(syncObj) { if (datasource == null) { datasource = getDatasource() } } } return datasource.getConnection(); } } class B { private static class DataSourceInstance { private static instance = getDatasource(); } private static Connection getConnection() { return DataSourceInstance.instance.getConnection(); } } |
|
返回顶楼 | |
发表时间:2011-02-18
最后修改:2011-02-18
fangshun说的很对:在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁!
fangshun 写道 在并发情况下,如果不加锁,datasource初始化阶段可能产生多个datasource实例,但是你的全局量最终只会使用一个,而多的几个就被分配个其他的并发线程了,这样就不能严格保证实例的唯一性,这就是单例模式的问题! 加了锁的这个类方法,肯定会产生线程排队问题,而且如此基础的类,一定会极大的产生性能影响! 建议,在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁! //静态块, 类在加载中实例化datasource { Connection conn = null; try { if (datasource == null) { Context ctx = new InitialContext(); datasource = (DataSource) ctx.lookup(JNDI_NAME); conn = datasource.getConnection(); } } catch (NamingException ex) { throw new DBAccessException("Cannot get DataSource", ex); } finally { if(conn!=null){ conn.close(); } } } public static Connection getConnection() throws DBAccessException { Connection conn = null; try { conn = datasource.getConnection(); if (conn == null) { throw new DBAccessException("Cannot get Connection."); } } catch (SQLException ex) { throw new DBAccessException("Cannot get Connection.", ex); } return conn; } |
|
返回顶楼 | |
发表时间:2011-02-18
最后修改:2011-02-18
yumcn.com 写道 public static Connection getConnection() throws DBAccessException {}
private static synchronized DataSource getDataSource() throws DBAccessException {} 去看看方法上加static的含义吧,方法上加了static,意味着这个方法是同步的,所以private static synchronized DataSource getDataSource()中的synchronized 是多余的。 另外fangshun说的很对,多好的建议:在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁! fangshun 写道 在并发情况下,如果不加锁,datasource初始化阶段可能产生多个datasource实例,但是你的全局量最终只会使用一个,而多的几个就被分配个其他的并发线程了,这样就不能严格保证实例的唯一性,这就是单例模式的问题! 加了锁的这个类方法,肯定会产生线程排队问题,而且如此基础的类,一定会极大的产生性能影响! 建议,在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁! 谁告诉你:方法前加上了static就是同步的? |
|
返回顶楼 | |
发表时间:2011-02-18
同步和静态有个毛的关系
![]() |
|
返回顶楼 | |