单例的设计模式中,一些代码的写法会存在线程安全的问题,举例如下:
(1)单例模式的懒汉式[线程不安全,不可用]
public class Singleton {
private static Singleton instance=null;
private Singleton() {};
public static Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
这种方式是在调用getInstance方法的时候才创建对象的,所以它就被称为懒汉模式。
这是存在线程安全问题的,那具体是存在怎样的线程安全问题?怎样导致这种问题的?好,我们来说一下什么情况下这种写法会有问题。在运行过程中可能存在这么一种情况:多个线程去调用getInstance方法来获取Singleton的实例,那么就有可能发生这样一种情况,当第一个线程在执行if(instance==null)时,此时instance是为null的进入语句。在还没有执行instance=new Singleton()时(此时instance是为null的)第二个线程也进入了if(instance==null)这个语句,因为之前进入这个语句的线程中还没有执行instance=new Singleton(),所以它会执行instance = new Singleton()来实例化Singleton对象,因为第二个线程也进入了if语句所以它会实例化Singleton对象。这样就导致了实例化了两个Singleton对象。所以单例模式的懒汉式是存在线程安全的,既然它存在问题,那么可能有解决办法,于是就有下面加锁这种写法。
(2)懒汉式线程安全的[线程安全,效率低不推荐使用]
public class Singleton {
private static Singleton instance=null;
private Singleton() {};
public static synchronized Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
缺点:效率太低了,每个线程在想获得类的实例的时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面想获得该实例,直接return就行了。方法进行同步效率太低要改进。
(3)单例模式懒汉式[线程不安全,不可用]
public class Singleton7 {
private static Singleton instance=null;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
}
这种写法也是不安全的,当一个线程还没有实例化Singleton时另一个线程执行到if(instance == null)这个判断时语句机会进入if语句,虽然加了锁,但是等到第一个线程执行完instance=new Singleton()跳出这个锁时,另一个进入if语句的线程同样会实例化另外一个SIngleton对象。因为这种改进方法不可行。
总结:
以上就是单例模式中,会引发的线程安全问题了