3 回答
TA贡献1946条经验 获得超3个赞
您正在实现惰性初始化模式-首次使用实例时在其中创建实例。
但是有一个简单的技巧,可以让你的代码,一个线程的实现并不需要同步!它称为“ 按需初始化持有人”习惯用法,它看起来像这样:
public class CassandraAstyanaxConnection {
private CassandraAstyanaxConnection(){ }
private static class Holder {
private static final CassandraAstyanaxConnection INSTANCE = new CassandraAstyanaxConnection();
}
public static CassandraAstyanaxConnection getInstance() {
return Holder.INSTANCE;
}
// rest of class omitted
}
此代码在首次调用时初始化实例getInstance(),并且重要的是由于类加载器的约定,不需要同步:
类加载器在首次访问类时加载类(在这种情况下Holder,唯一的访问是在getInstance()方法内)
当加载了一个类,并且在任何人都可以使用它之前,请确保所有静态初始化程序都将被执行(这是在Holder静态块触发时)
类加载器内置了自己的同步功能,可以确保上述两点是线程安全的
每当需要懒惰初始化时,我都会使用这巧妙的小技巧。final即使实例是惰性创建的,您也可以获得实例的奖励。还要注意代码是多么干净和简单。
编辑:您应该将所有构造函数设置为私有或受保护。设置并清空私有构造函数即可完成工作
TA贡献1833条经验 获得超4个赞
以上所有方法都急于初始化对象。这个怎么样。这将帮助您懒惰地初始化ur类。您可能有重物,并且不想在启动时进行初始化。
public class MySinglton {
private MySinglton (){}
private static volatile MySinglton s;
public static MySinglton getInstance(){
if (s != null ) return s;
synchronized(MySinglton.class){
if (s == null ) {
s = new MySinglton();
}
}
return s;
}
}
TA贡献1848条经验 获得超6个赞
不,如果在pulbic方法上返回的值是可更改的对象,则它不是线程安全的。
对于此类,线程安全的一种方法是将其更改为不可变的。
为此,您可以这样更改此方法:
public Keyspace getKeyspace() {
// make a copy to prevent external user to modified or ensure that Keyspace is immutable, in that case, you don't have to make a copy
return new Keyspace( keyspace );
}
public ColumnFamily<String, String> getEmp_cf() {
// Same principle here. If ColumnFamily is immutable, you don't have to make a copy. If its not, then make a copy
return new ColumnFamily( emp_cf );
}
在本书《Java并发实践》中,您可以了解这种不变性的原理。
添加回答
举报