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