使用锁的缓存的一个实际应用。这儿用到了dlc锁。
public abstract class MyDao {
private volatile String dbTypeStr = ""; //volatile 保证有序性,防止指令重排
protected abstract JdbcTemplate getJdbcTemplate();
//DCL 锁,性能好
public DbEnum getDbType(){
if(StringUtils.isBlank(this.dbTypeStr)){ //double check lock
synchronized (this) {
if (StringUtils.isBlank(this.dbTypeStr)) {
this.dbTypeStr = DbEnum.toStr(EasyDao.dbType(this.getJdbcTemplate()));
}
}
}
return DbEnum.toEnum(this.dbTypeStr);
}
//普通锁 ,性能不好
public synchronized DbEnum getDbTypeSync(){
if(StringUtils.isNotBlank(this.dbTypeStr)){
return DbEnum.toEnum(this.dbTypeStr);
}
DbEnum dbEnum = dbType(this.getJdbcTemplate());
this.dbTypeStr = DbEnum.toStr(dbEnum);
return dbEnum;
}
//注意:这个要消耗性能的,请用一次就缓存下来.
public static DbEnum dbType(JdbcTemplate jdbcTemplate){
try {
String driverName = jdbcTemplate.getDataSource().getConnection().getMetaData().getDriverName();
if(driverName.startsWith("MySQL")){
return DbEnum.MySql;
}
else if(driverName.startsWith("PostgreSQL")){
return DbEnum.PgSql;
}
else {
Asserts.fail(-1001,"不支持的数据库:"+driverName);
return null;
}
}
catch (SQLException sqlException){
Asserts.fail(-1001,sqlException.getMessage());
return null;
}
}
}
网友评论