tbwshc

java 单例加锁方法的讨论

java 单例加锁方法:

ScheduleEngine是个单例类,在获得实例的方法getinstance中,两次判断其是否为空,有利于多线程的并发操作。

使得实例化时,只在第一次加锁,这样效率会有提高。

 

Java代码 复制代码 收藏代码
  1. class ScheduleEngine{   
  2.        
  3.         private static Lock instanceLock=new ReentrantLock();   
  4.            
  5.         private ScheduleEngine() {   
  6.             setproperties;   
  7.         }   
  8.            
  9.         public static ScheduleEngine getInstance(int temphandlerType) {   
  10.             if(null==engine) {   
  11.                 instanceLock.lock();   
  12.                 try  
  13.                 {   
  14.                 if(null==engine)   
  15.                 {   
  16.                 handlerType=temphandlerType;   
  17.                 engine=new ScheduleEngine(temphandlerType);   
  18.                 }   
  19.            
  20.                 }   
  21.                 finally  
  22.                 {   
  23.                 instanceLock.unlock();   
  24.                 }   
  25.             }   
  26.             return engine;   
  27.             }    
  28.     }  

 

初始实例化 单例c3p0对象的方法,常用的是

 

Java代码 复制代码 收藏代码
  1. public final class ConnectionManager {   
  2.   
  3.     private static ConnectionManager instance;   
  4.     private static ComboPooledDataSource cpds;   
  5.   
  6.     private static String c3p0Properties;   
  7.   
  8.     /**  
  9.      * 从数据库连接池取连接  
  10.      * @throws Exception  
  11.      */  
  12.     private ConnectionManager() throws Exception {   
  13.         Properties p = new Properties();   
  14.         c3p0Properties = System.getProperty("user.dir") +   
  15.                 "/mom_project_config/database.properties";   
  16. //      p.load(this.getClass().getClassLoader().getResourceAsStream(c3p0Properties));   
  17.         p.load(new BufferedInputStream(new FileInputStream(c3p0Properties)));   
  18. //      String url = p.getProperty("url") + p.getProperty("database");   
  19.         String url = p.getProperty("url") + p.getProperty("database")+"?useUnicode=true&characterEncoding=UTF-8";   
  20.         cpds = new ComboPooledDataSource();   
  21.         cpds.setDriverClass(p.getProperty("driverclass"));   
  22.         cpds.setJdbcUrl(url);   
  23.         cpds.setUser(p.getProperty("user"));   
  24.         cpds.setPassword(p.getProperty("password"));   
  25.         // 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 acquireIncrement   
  26.         cpds.setAcquireIncrement(Integer.valueOf(p   
  27.                 .getProperty("acquireincrement")));   
  28.         // 定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 acquireRetryAttempts   
  29.         cpds.setAcquireRetryAttempts(Integer.valueOf(p   
  30.                 .getProperty("acquireretryattempts")));   
  31.         // 两次连接中间隔时间,单位毫秒。Default: 1000 acquireRetryDelay   
  32.         cpds.setAcquireRetryDelay(Integer.valueOf(p   
  33.                 .getProperty("acquireretrydelay")));   
  34.         // 自动提交事务;连接关闭时默认将所有未提交的操作回滚。Default: false autoCommitOnClose   
  35.         cpds.setAutoCommitOnClose(Boolean.valueOf(p   
  36.                 .getProperty("autocommitonclose")));   
  37.         // 当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,   
  38.         // 如设为0则无限期等待.单位毫秒,默认为0   
  39.         cpds.setCheckoutTimeout(Integer.valueOf(p   
  40.                 .getProperty("checkouttimeout")));   
  41.         // 每多少秒检查所有连接池中的空闲连接。默认为0表示不检查。Default: 0 idleConnectionTestPeriod   
  42.         cpds.setIdleConnectionTestPeriod(Integer.valueOf(p   
  43.                 .getProperty("idleconnectiontestperiod")));   
  44.         // 最大空闲时间,25000秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 maxIdleTime   
  45.         cpds.setMaxIdleTime(Integer.valueOf(p.getProperty("maxidletime")));   
  46.         // 初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 initialPoolSize   
  47.         cpds.setInitialPoolSize(Integer.valueOf(p   
  48.                 .getProperty("initialpoolsize")));   
  49.         // 连接池中保留的最小连接数。   
  50.         cpds.setMinPoolSize(Integer.valueOf(p.getProperty("minpoolsize")));   
  51.         // 连接池中保留的最大连接数。Default: 15 maxPoolSize   
  52.         cpds.setMaxPoolSize(Integer.valueOf(p.getProperty("maxpoolsize")));   
  53.         // JDBC的标准参数,用以控制数据源内加载的PreparedStatement数据.但由于预缓存的Statement属于单个Connection而不是整个连接池.所以   
  54.         // 设置这个参数需要考滤到多方面的因素,如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭.默认为0;   
  55.         cpds.setMaxStatements(Integer.valueOf(p.getProperty("maxstatements")));   
  56.         // 连接池内单个连接所拥有的最大缓存被关闭.默认为0;   
  57.         cpds.setMaxStatementsPerConnection(Integer.valueOf(p   
  58.                 .getProperty("maxstatementsperconnection")));   
  59.         // C3P0是异步操作的,缓慢的JDBC操作通过帮助进程完成.扩展这些操作可以有效的提升性能,通过多数程实现多个操作同时被执行.默为为3   
  60.         cpds.setNumHelperThreads(Integer.valueOf(p   
  61.                 .getProperty("numhelperthreads")));   
  62.         // 用户修改系统配置参数执行前最多等待的秒数.默认为300;   
  63.         cpds.setPropertyCycle(Integer.valueOf(p.getProperty("propertycycle")));   
  64.         // 如果设为true那么在取得连接的同时将校验连接的有效性。Default: false testConnectionOnCheckin   
  65.         cpds.setTestConnectionOnCheckin(Boolean.valueOf(p   
  66.                 .getProperty("testconnectiononcheckin")));   
  67.         // 因性能消耗大请只在需要的时候使用它。   
  68.         // 如果设为true那么在每个connection提交的时候都将校验其有效性。   
  69.         // 建议使用idleConnectionTestPeriod或automaticTestTable等方法来提升连接测试的性能。Default:   
  70.         // false testConnectionOnCheckout   
  71.         cpds.setTestConnectionOnCheckout(Boolean.valueOf(p   
  72.                 .getProperty("testconnectionOncheckout")));   
  73.         // 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。   
  74.         // 但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。   
  75.         // 如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。Default: false   
  76.         // breakAfterAcquireFailure   
  77.         cpds.setBreakAfterAcquireFailure(Boolean.valueOf(p   
  78.                 .getProperty("breakafteracquirefailure")));   
  79.   
  80.     }   
  81.   
  82.     /**  
  83.      * 获得ConnectionManager单例对象  
  84.      * @return  
  85.      */  
  86.     public synchronized static ConnectionManager getInstance() {   
  87.         if (instance == null) {   
  88.             try {   
  89.                 instance = new ConnectionManager();   
  90.             } catch (Exception e) {   
  91.                 e.printStackTrace();   
  92.             }   
  93.         }   
  94.         return instance;   
  95.     }   
  96.   
  97.     /**  
  98.      * 获得连接  
  99.      * @return  
  100.      */  
  101.     public Connection getContection() {   
  102.         try {   
  103.             return cpds.getConnection();   
  104.         } catch (SQLException e) {   
  105.             e.printStackTrace();   
  106.         }   
  107.         return null;   
  108.     }  

 

在初始化获得单例的方法上面加锁,不利于并发操作的执行,用第一段代码两次判断是否为空的方式,可以减少代码执行中锁的引用。 不足之处烦请朋友们指正。。

posted on 2012-08-03 17:28 chen11-1 阅读(2327) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: