论坛首页 Java企业应用论坛

一个关于连接池很基础的讨论.

浏览 12324 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (19) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-02-18  
je回复这么垃圾吗,什么双重检测都出来了,我来告诉LZ可以要也可以不要,如果业务中要只调用getDataSource方法你说要不要呢,所以按照junit 的流程应该要
0 请登录后投票
   发表时间:2011-02-18  
在并发情况下,如果不加锁,datasource初始化阶段可能产生多个datasource实例,但是你的全局量最终只会使用一个,而多的几个就被分配个其他的并发线程了,这样就不能严格保证实例的唯一性,这就是单例模式的问题!

加了锁的这个类方法,肯定会产生线程排队问题,而且如此基础的类,一定会极大的产生性能影响!

建议,在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁!
2 请登录后投票
   发表时间:2011-02-18  
fangshun 写道
在并发情况下,如果不加锁,datasource初始化阶段可能产生多个datasource实例,但是你的全局量最终只会使用一个,而多的几个就被分配个其他的并发线程了,这样就不能严格保证实例的唯一性,这就是单例模式的问题!

加了锁的这个类方法,肯定会产生线程排队问题,而且如此基础的类,一定会极大的产生性能影响!

建议,在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁!



那么多回复,终于见到一个好使的。
0 请登录后投票
   发表时间:2011-02-18  
fangshun 写道
在并发情况下,如果不加锁,datasource初始化阶段可能产生多个datasource实例,但是你的全局量最终只会使用一个,而多的几个就被分配个其他的并发线程了,这样就不能严格保证实例的唯一性,这就是单例模式的问题!

加了锁的这个类方法,肯定会产生线程排队问题,而且如此基础的类,一定会极大的产生性能影响!

建议,在整个应用启动的时候,去初始化datasource实例,保证实例的唯一性,也就可以取消对类方法的锁!



是单例的问题。采用 内部类进行延迟加载 也可以避免对类方法的锁。。。可以看看 研读设计模式 里面关于单例的讲解,非常清晰。
0 请登录后投票
   发表时间:2011-02-18  
首先这段代码设计的不好。有种乱七八糟的感觉,看起来写代码的人想延迟加载,但是表现的有点模糊。

实际上加第一句的好处在于节省效率,只要datasouce已经初始化过了,就不再理会初始化的问题。因为初始化涉及到一个锁,所以效率的提升在这一句应该比较大。

跟多重检查也没关系。
0 请登录后投票
   发表时间:2011-02-18  
rong889 写道
假设刚开始datasource为null,这时候有10个线程同时访问getConnection(),同时执行到
# if (datasource == null) {                    
#         getDataSource();                     
#     }

那么getDataSource()会被调用10次,如果getDataSource()中不加if (datasource == null),datasource 就会被初始化10次。
因此加上还是有必要的,能够避免datasource被重复初始化。


赞同 rong889 的说法。
第一个null判断是为了提高效率,第二个是为了保证datasource的唯一性。
0 请登录后投票
   发表时间: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();
    }
}
0 请登录后投票
   发表时间: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;                          
}    
  

0 请登录后投票
   发表时间: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就是同步的?
0 请登录后投票
   发表时间:2011-02-18  
同步和静态有个毛的关系
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics