-
懒汉式
public class Singleton { private static Singleton instance = null; // 不允许外部实例话 private Singleton(); public static Singleton getInstance(){ if (null == instance){ instence = new Singleton() } return instance; } }
为什么说它线程不安全?
同时运行线程A和线程B,它们都要调用Singleton.getInstance(),线程A判断instance为空,线程B也会判断instance为空,实际上,线程A与线程B中的获取的Singleton不是同一对象
如何保证单例的线程安全?
public class Singleton {
//添加volatile 保护变量安全
private volatile static Singleton instance = null;
// 不允许外部实例话
private Singleton();
//双重检查锁定
public static Singleton getInstance(){
if (null == instance){
synchronized (Singleton.class){
if(null == instance){
instence = new Singleton()
}
}
}
return instance;
}
}
- 饿汉式
public class Singleton {
private static Singleton instance = new Singleton();
//不允许外部实例话
private Singleton(){}
public static Singletion getInstance(){
return instance;
}
}
基于ClassLoader机制避免了多线程的同步问题
- 静态内部类
public class Singleton {
private static class SingletonHodler {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton(){}
public static final Singleton getInstance(){
return SingletonHodler.INSTANCE;
}
}
基于ClassLoader机制,Singleton类被装载了,instance不一定被初始化
- 枚举单例
class B {
}
enum Singleton {
INSTANCE;
private B b;
private Singleton(){
b = new B();
}
public B getInstance(){
return b;
}
}
public static void main(String[] args) {
System.out.println(Singleton.INSTANCE.getInstance().hashCode());
System.out.println(Singleton.INSTANCE.getInstance().hashCode());
}
hashcode是一致的
参考:
http://www.blogjava.net/kenzhh/archive/2013/03/15/357824.html
https://www.cnblogs.com/happy4java/p/11206105.html
https://www.jianshu.com/p/d35f244f3770