【发布时间】:2013-04-19 07:17:19
【问题描述】:
我相信我写的下面的单例类是Thread Safe。
在某些情况下,双重检查锁定模式显然可能会遇到问题(我已经看到有人警告过它,尽管这是不久前的事情,所以我现在只是在谷歌上搜索答案)
我现在不确定,我下面的 Singleton 类中的 Double Checked 锁定模式是否会有任何问题。我添加了双重检查锁定模式,以使程序运行得稍微快一些。
public class CassandraAstyanaxConnection {
private static CassandraAstyanaxConnection _instance;
private static final Object syncObject = new Object();
private AstyanaxContext<Keyspace> context;
private Keyspace keyspace;
private ColumnFamily<String, String> emp_cf;
public static CassandraAstyanaxConnection getInstance() {
if (_instance == null) {
synchronized(syncObject) {
if (_instance == null) {
_instance = new CassandraAstyanaxConnection();
}
}
}
return _instance;
}
/**
* Creating Cassandra connection using Astyanax client
*
*/
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(1)
.setSeeds("127.0.0.1:9160")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2"))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
/**
* returns the keyspace
*
* @return
*/
public Keyspace getKeyspace() {
return keyspace;
}
public ColumnFamily<String, String> getEmp_cf() {
return emp_cf;
}
}
我的代码在上面的 Singleton 类中是否存在双重检查锁定模式的问题?
以及创建单例类线程安全的最佳方法是什么。那么持有人类成语呢?我可以在我的单身课程中使用它吗?
基于我上面的 Singleton 类的任何示例都将帮助我更好地理解如何编写更好的线程安全的 Singleton 类。
感谢您的帮助。
更新代码:-
经过一些建议,我对代码进行了更改-
public class CassandraAstyanaxConnection {
private static class ConnectionHolder {
public static CassandraAstyanaxConnection connection = new CassandraAstyanaxConnection()
}
public static CassandraAstyanaxConnection getInstance() {
return ConnectionHolder.connection;
}
/**
* Creating Cassandra connection using Astyanax client
*
*/
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(1)
.setSeeds("127.0.0.1:9160")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2"))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
/**
* returns the keyspace
*
* @return
*/
public Keyspace getKeyspace() {
return keyspace;
}
public ColumnFamily<String, String> getEmp_cf() {
return emp_cf;
}
}
如果这看起来正确,请告诉我。
【问题讨论】:
-
1) 创建类
final2) 创建静态实例final3) 覆盖readResolve()以返回实例 4) 为了完美,从clone()抛出异常。 5)synchronizegetInstance()
标签: java singleton double-checked-locking