版权声明:本文为HCG原创文章,未经博主允许不得转载。请联系[email protected] https://blog.csdn.net/qq_39455116/article/details/86701380
单例模式线程安全吗?
单例模式作为一种常见的设计模式,在程序中非常常见,主要是为了保证一个类只有一个唯一的对象。
从简单的“饿汉式”、“懒汉式”→利用 synchronized 和 复杂的“双重校验DCL模式”,是一个考虑线程安全的过程
那么单例模式线程安全吗
1. 静态的饿汉式单例模式是线程安全的
那非静态的饿汉单例模式呢?
答案是:没有非静态的饿汉单例模式
// 线程安全
public class EhanMonitor {
private static EhanMonitor ehanMonitor =new EhanMonitor();
private EhanMonitor (){
}
public static EhanMonitor getEhanMonitor(){
return ehanMonitor ;
}
}
2. 在方法前面加synchronized的懒汉单例模式是线程安全的,但是效率低
//线程安全
public class Singleton2 {
private Singleton2(){
}
private static Singleton2 instance;
public static synchronized Singleton2 getInstance(){
if(instance == null) {//1
instance = new Singleton2();//2
}
return instance;
}
}
3. 双重校验DCL模式的懒汉单例模式不是线程安全的
//不是线程安全
public class Monitor {
private static Monitor monitor =null ;
private Monitor(){}
public static Monitor getMonitor(){
if(monitor ==null){
synchronized (Monitor.class){
if(monitor ==null){
monitor =new Monitor();
}
}
}
return monitor ;
}
因为下面的2,3步骤会重排序
mem = allocate(); //为单例对象分配内存空间.
instance = mem; //注意,instance 引用现在是非空,但还未初始化
ctorSingleton(instance); //为单例对象通过instance调用构造函数
4. 双重校验的volatile DCL模式是线程安全的
添加volatile 可以禁止2,3步骤的重排序
//线程安全
public class Monitor {
private static volatile Monitor monitor =null ;
private Monitor(){}
public static Monitor getMonitor(){
if(monitor ==null){
synchronized (Monitor.class){
if(monitor ==null){
monitor =new Monitor();
}
}
}
return monitor ;
}
5. 静态内部类实现的单例模式是线程安全的
//线程安全
public class ClassMonitor {
private static class MonitorCreator {
private static ClassMonitor classMonitor = new ClassMonitor();
}
private ClassMonitor() {
System.out.println("构造方法初始化");
}
public static ClassMonitor getInstance() {
System.out.println("静态内部类获取");
return MonitorCreator.classMonitor;
}