饿汉模式
类加载时便实例化,线程安全。
public class HungrySingleton {
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){
}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
懒汉模式
使用时再初始化,但线程不安全
public class LazySingleton {
private static LazySingleton singleton;
private LazySingleton(){
}
public static LazySingleton getInstance(){
if (singleton !=null){
return singleton;
}
singleton = new LazySingleton();
return singleton;
}
}
懒汉模式使用synchronized同步
public class SyncLazySingleton {
private static SyncLazySingleton singleton;
private SyncLazySingleton(){
}
public synchronized static SyncLazySingleton getInstance(){
if (singleton !=null){
return singleton;
}
singleton = new SyncLazySingleton();
return singleton;
}
}
双重检查
对象的引用需要加volatile关键字。因为对象的创建是非原子的。会经历一下三个步骤。
- 申请内存
- 调用构造方法
- 对象引用指向申请的内存
其中2,3步骤可能发生重排序。多线程情况下可能导致一个不完整的对象提前暴露。
public class DoubleCheckSingleton {
private volatile static DoubleCheckSingleton singleton;
private DoubleCheckSingleton(){}
public static DoubleCheckSingleton getInstance(){
if (singleton == null){
synchronized (DoubleCheckSingleton.class){
if (singleton == null){
singleton = new DoubleCheckSingleton();
}
}
}
return singleton;
}
}
静态内部类
线程安全,且延时加载,如果需要序列化和反序列化会生成多个对象。
public class InnerClassSingleton {
private static class SingletonHandler{
private static InnerClassSingleton singleton = new InnerClassSingleton();
}
private InnerClassSingleton(){
}
public static InnerClassSingleton getInstance(){
return SingletonHandler.singleton;
}
}
枚举方式
线程安全,且延时加载,如果需要序列化和反序列化不会生成多个对象。
public class EnumSingleton {
public enum Singleton{
INSTANCE;
private EnumSingleton singleton;
Singleton(){
singleton = new EnumSingleton();
}
public EnumSingleton getSingleton(){
return singleton;
}
}
public static void main(String[] args) {
System.out.println(Singleton.INSTANCE.getSingleton());
}
}
网友评论