单例模式在java中的定义:一个类有且仅有一个实例,并且自行实例化向整个系统提供。在单例模式中要注意两点,
- 构造方法私有并不能保证客户端不能创建对象,客户端可以通过java反射机制实例化对象,防止这种情况的办法就是在构造器中设置一个sentinel,保证只实例化一次,再次实例化抛出RuntimeException异常。
- 单例模式要考虑多线程下的情形,考虑在实例化对象的代码块上同步
下面给出几种实现单例模式的方法:
-
饿汉式单例模式,加载类的时候实例化对象
public class EargeSingle {
private static boolean sentinel= false;
private static final EargeSingle eargeSingle = new EargeSingle();
private EargeSingle(){
if(!sentinel){
sentinel = true;
}else{
throw new RuntimeException("已经实例化了");
}
}
public static EargeSingle getInstance(){
return eargeSingle;
}
} -
嵌套类的方式,jvm加载类初始化静态域是线程安全的。这个可以说是完美的单例模式,既延迟初始化,又不使用额外的同步
public class NestedSingleton {
private static class Holder{
private static NestedSingleton singleton = new NestedSingleton();
}
//不再重复写防止客户端实例化对象
private NestedSingleton(){}public static NestedSingleton getInstance(){ return Holder.singleton; } }
-
同步延迟加载方式,也就是双重检查的方式,但是由于重排序的问题,需要在实例变量加上volatile关键字,表示一个线程的对对象的修改会立即通知其他的线程。
public class SynchronizeSingleton { private static volatile SynchronizeSingleton singleton; private SynchronizeSingleton(){} public static SynchronizeSingleton getInstance(){ if(singleton == null){ create(); } return singleton; } private synchronized static void create() { if(singleton == null){ singleton = new SynchronizeSingleton(); } } }
网友评论