java 單例加鎖方法:
ScheduleEngine是個單例類,在獲得實例的方法getinstance中,兩次判斷其是否為空,有利于多線程的并發操作。
使得實例化時,只在第一次加鎖,這樣效率會有提高。
- 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;
- }
- }
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;
}
}
初始實例化 單例c3p0對象的方法,常用的是
public final class ConnectionManager {
private static ConnectionManager instance;
private static ComboPooledDataSource cpds;
private static String c3p0Properties;
/**
* 從數據庫連接池取連接
* @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"));
// 當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數。Default: 3 acquireIncrement
cpds.setAcquireIncrement(Integer.valueOf(p
.getProperty("acquireincrement")));
// 定義在從數據庫獲取新連接失敗后重復嘗試的次數。Default: 30 acquireRetryAttempts
cpds.setAcquireRetryAttempts(Integer.valueOf(p
.getProperty("acquireretryattempts")));
// 兩次連接中間隔時間,tb單位毫秒。Default: 1000 acquireRetryDelay
cpds.setAcquireRetryDelay(Integer.valueOf(p
.getProperty("acquireretrydelay")));
// 自動提交事務;連接關閉時默認將所有未提交的操作回滾。Default: false autoCommitOnClose
cpds.setAutoCommitOnClose(Boolean.valueOf(p
.getProperty("autocommitonclose")));
// 當連接池用完時客戶端調用getConnection()后等待獲取新連接的時間,超時后將拋出SQLException,
// 如設為0則無限期等待.單位毫秒,默認為0
cpds.setCheckoutTimeout(Integer.valueOf(p
.getProperty("checkouttimeout")));
// 每多少秒檢查所有連接池中的空閑連接。默認為0表示不檢查。Default: 0 idleConnectionTestPeriod
cpds.setIdleConnectionTestPeriod(Integer.valueOf(p
.getProperty("idleconnectiontestperiod")));
// 最大空閑時間,25000秒內未使用則連接被丟棄。若為0則永不丟棄。Default: 0 maxIdleTime
cpds.setMaxIdleTime(Integer.valueOf(p.getProperty("maxidletime")));
// 初始化時獲取三個連接,取值應在minPoolSize與maxPoolSize之間。Default: 3 initialPoolSize
cpds.setInitialPoolSize(Integer.valueOf(p
.getProperty("initialpoolsize")));
// 連接池中保留的最小連接數。
cpds.setMinPoolSize(Integer.valueOf(p.getProperty("minpoolsize")));
// 連接池中保留的最大連接數。Default: 15 maxPoolSize
cpds.setMaxPoolSize(Integer.valueOf(p.getProperty("maxpoolsize")));
// JDBC的標準參數,用以控制數據源內加載的PreparedStatement數據.但由于預緩存的Statement屬于單個Connection而不是整個連接池.所以
// 設置這個參數需要考濾到多方面的因素,如果maxStatements與maxStatementsPerConnection均為0,則緩存被關閉.默認為0;
cpds.setMaxStatements(Integer.valueOf(p.getProperty("maxstatements")));
// 連接池內單個連接所擁有的最大緩存被關閉.默認為0;
cpds.setMaxStatementsPerConnection(Integer.valueOf(p
.getProperty("maxstatementsperconnection")));
// C3P0是異步操作的,緩慢的JDBC操作通過幫助進程完成.擴展這些操作可以有效的提升性能,通過多數程實現多個操作同時被執行.默為為3
cpds.setNumHelperThreads(Integer.valueOf(p
.getProperty("numhelperthreads")));
// 用戶修改系統配置參數執行前最多等待的秒數.默認為300;
cpds.setPropertyCycle(Integer.valueOf(p.getProperty("propertycycle")));
// 如果設為true那么在取得連接的同時將校驗連接的有效性。Default: false testConnectionOnCheckin
cpds.setTestConnectionOnCheckin(Boolean.valueOf(p
.getProperty("testconnectiononcheckin")));
// 因性能消耗大請只在需要的時候使用它。
// 如果設為true那么在每個connection提交的時候都將校驗其有效性。
// 建議使用idleConnectionTestPeriod或automaticTestTable等方法來提升連接測試的性能。Default:
// false testConnectionOnCheckout
cpds.setTestConnectionOnCheckout(Boolean.valueOf(p
.getProperty("testconnectionOncheckout")));
// 獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。
// 但是數據源仍有效保留,并在下次調用getConnection()的時候繼續嘗試獲取連接。
// 如果設為true,那么在嘗試獲取連接失敗后該數據源將申明已斷開并永久關閉。Default: false
// breakAfterAcquireFailure
cpds.setBreakAfterAcquireFailure(Boolean.valueOf(p
.getProperty("breakafteracquirefailure")));
}
/**
* 獲得ConnectionManager單例對象
* @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;
}
在初始化獲得單例的方法上面加鎖,不利于并發操作的執行,用第一段代碼兩次判斷是否為空的方式,可以減少代碼執行中鎖的引用。 不足之處煩請朋友們指正。。