java 單例加鎖方法的討論
java 單例加鎖方法:
ScheduleEngine是個(gè)單例類,在獲得實(shí)例的方法getinstance中,兩次判斷其是否為空,有利于多線程的并發(fā)操作。
使得實(shí)例化時(shí),只在第一次加鎖,這樣效率會(huì)有提高。
- class ScheduleEngine{
- private static Lock instanceLock=new ReentrantLock();
- private ScheduleEngine() {
- setproperties;
- }
- public static ScheduleEngine getInstance(int temphandlerType) {
- if(null==engine) {
- instanceLock.lock();
- try
- {
- if(null==engine)
- {
- handlerType=temphandlerType;
- engine=new ScheduleEngine(temphandlerType);
- }
- }
- finally
- {
- instanceLock.unlock();
- }
- }
- return engine;
- }
- }
初始實(shí)例化 單例c3p0對(duì)象的方法,常用的是
- public final class ConnectionManager {
- private static ConnectionManager instance;
- private static ComboPooledDataSource cpds;
- private static String c3p0Properties;
- /**
- * 從數(shù)據(jù)庫(kù)連接池取連接
- * @throws Exception
- */
- private ConnectionManager() throws Exception {
- Properties p = new Properties();
- c3p0Properties = System.getProperty("user.dir") +
- "/mom_project_config/database.properties";
- // p.load(this.getClass().getClassLoader().getResourceAsStream(c3p0Properties));
- p.load(new BufferedInputStream(new FileInputStream(c3p0Properties)));
- // String url = p.getProperty("url") + p.getProperty("database");
- String url = p.getProperty("url") + p.getProperty("database")+"?useUnicode=true&characterEncoding=UTF-8";
- cpds = new ComboPooledDataSource();
- cpds.setDriverClass(p.getProperty("driverclass"));
- cpds.setJdbcUrl(url);
- cpds.setUser(p.getProperty("user"));
- cpds.setPassword(p.getProperty("password"));
- // 當(dāng)連接池中的連接耗盡的時(shí)候c3p0一次同時(shí)獲取的連接數(shù)。Default: 3 acquireIncrement
- cpds.setAcquireIncrement(Integer.valueOf(p
- .getProperty("acquireincrement")));
- // 定義在從數(shù)據(jù)庫(kù)獲取新連接失敗后重復(fù)嘗試的次數(shù)。Default: 30 acquireRetryAttempts
- cpds.setAcquireRetryAttempts(Integer.valueOf(p
- .getProperty("acquireretryattempts")));
- // 兩次連接中間隔時(shí)間,單位毫秒。Default: 1000 acquireRetryDelay
- cpds.setAcquireRetryDelay(Integer.valueOf(p
- .getProperty("acquireretrydelay")));
- // 自動(dòng)提交事務(wù);連接關(guān)閉時(shí)默認(rèn)將所有未提交的操作回滾。Default: false autoCommitOnClose
- cpds.setAutoCommitOnClose(Boolean.valueOf(p
- .getProperty("autocommitonclose")));
- // 當(dāng)連接池用完時(shí)客戶端調(diào)用getConnection()后等待獲取新連接的時(shí)間,超時(shí)后將拋出SQLException,
- // 如設(shè)為0則無(wú)限期等待.單位毫秒,默認(rèn)為0
- cpds.setCheckoutTimeout(Integer.valueOf(p
- .getProperty("checkouttimeout")));
- // 每多少秒檢查所有連接池中的空閑連接。默認(rèn)為0表示不檢查。Default: 0 idleConnectionTestPeriod
- cpds.setIdleConnectionTestPeriod(Integer.valueOf(p
- .getProperty("idleconnectiontestperiod")));
- // 最大空閑時(shí)間,25000秒內(nèi)未使用則連接被丟棄。若為0則永不丟棄。Default: 0 maxIdleTime
- cpds.setMaxIdleTime(Integer.valueOf(p.getProperty("maxidletime")));
- // 初始化時(shí)獲取三個(gè)連接,取值應(yīng)在minPoolSize與maxPoolSize之間。Default: 3 initialPoolSize
- cpds.setInitialPoolSize(Integer.valueOf(p
- .getProperty("initialpoolsize")));
- // 連接池中保留的最小連接數(shù)。
- cpds.setMinPoolSize(Integer.valueOf(p.getProperty("minpoolsize")));
- // 連接池中保留的最大連接數(shù)。Default: 15 maxPoolSize
- cpds.setMaxPoolSize(Integer.valueOf(p.getProperty("maxpoolsize")));
- // JDBC的標(biāo)準(zhǔn)參數(shù),用以控制數(shù)據(jù)源內(nèi)加載的PreparedStatement數(shù)據(jù).但由于預(yù)緩存的Statement屬于單個(gè)Connection而不是整個(gè)連接池.所以
- // 設(shè)置這個(gè)參數(shù)需要考濾到多方面的因素,如果maxStatements與maxStatementsPerConnection均為0,則緩存被關(guān)閉.默認(rèn)為0;
- cpds.setMaxStatements(Integer.valueOf(p.getProperty("maxstatements")));
- // 連接池內(nèi)單個(gè)連接所擁有的最大緩存被關(guān)閉.默認(rèn)為0;
- cpds.setMaxStatementsPerConnection(Integer.valueOf(p
- .getProperty("maxstatementsperconnection")));
- // C3P0是異步操作的,緩慢的JDBC操作通過(guò)幫助進(jìn)程完成.擴(kuò)展這些操作可以有效的提升性能,通過(guò)多數(shù)程實(shí)現(xiàn)多個(gè)操作同時(shí)被執(zhí)行.默為為3
- cpds.setNumHelperThreads(Integer.valueOf(p
- .getProperty("numhelperthreads")));
- // 用戶修改系統(tǒng)配置參數(shù)執(zhí)行前最多等待的秒數(shù).默認(rèn)為300;
- cpds.setPropertyCycle(Integer.valueOf(p.getProperty("propertycycle")));
- // 如果設(shè)為true那么在取得連接的同時(shí)將校驗(yàn)連接的有效性。Default: false testConnectionOnCheckin
- cpds.setTestConnectionOnCheckin(Boolean.valueOf(p
- .getProperty("testconnectiononcheckin")));
- // 因性能消耗大請(qǐng)只在需要的時(shí)候使用它。
- // 如果設(shè)為true那么在每個(gè)connection提交的時(shí)候都將校驗(yàn)其有效性。
- // 建議使用idleConnectionTestPeriod或automaticTestTable等方法來(lái)提升連接測(cè)試的性能。Default:
- // false testConnectionOnCheckout
- cpds.setTestConnectionOnCheckout(Boolean.valueOf(p
- .getProperty("testconnectionOncheckout")));
- // 獲取連接失敗將會(huì)引起所有等待連接池來(lái)獲取連接的線程拋出異常。
- // 但是數(shù)據(jù)源仍有效保留,并在下次調(diào)用getConnection()的時(shí)候繼續(xù)嘗試獲取連接。
- // 如果設(shè)為true,那么在嘗試獲取連接失敗后該數(shù)據(jù)源將申明已斷開(kāi)并永久關(guān)閉。Default: false
- // breakAfterAcquireFailure
- cpds.setBreakAfterAcquireFailure(Boolean.valueOf(p
- .getProperty("breakafteracquirefailure")));
- }
- /**
- * 獲得ConnectionManager單例對(duì)象
- * @return
- */
- public synchronized static ConnectionManager getInstance() {
- if (instance == null) {
- try {
- instance = new ConnectionManager();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return instance;
- }
- /**
- * 獲得連接
- * @return
- */
- public Connection getContection() {
- try {
- return cpds.getConnection();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- return null;
- }
在初始化獲得單例的方法上面加鎖,不利于并發(fā)操作的執(zhí)行,用第一段代碼兩次判斷是否為空的方式,可以減少代碼執(zhí)行中鎖的引用。 不足之處煩請(qǐng)朋友們指正。。
posted on 2012-08-03 17:28 chen11-1 閱讀(2340) 評(píng)論(0) 編輯 收藏