Java中的单例模式是指某个类只有一个实例,并提供全局访问点。在多线程的环境下,单例模式需要控制并发访问下的线程安全。下面我们来详细讲解“Java多线程之线程安全的单例模式”的完整攻略。
线程安全的单例模式
线程安全的单例模式可以通过同步方法或同步块来实现。下面是一个使用同步方法实现线程安全单例模式的示例。
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
在这个示例中,getInstance()方法是被synchronized关键字修饰的同步方法,这种方式虽然能够保证线程的安全性,但是锁的机制会导致程序的性能会受到影响。
下面是一个使用同步块实现的线程安全单例模式的示例。
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
在这个示例中,我们使用了一个同步块,在同步块中再次检查instance是否为null,确保在多线程环境下只会生成一个唯一的实例。这种方式比同步方法效率更高。
示例说明
下面是两个示例说明,通过这两个示例我们可以更好的理解线程安全的单例模式。
示例一:懒汉式单例模式
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
在这个示例中,我们通过synchronized关键字来保证线程的安全性,但是同步锁会导致性能问题。当多个线程同时调用getInstance()方法时,只有一个线程能够进入同步锁区域。其他线程需要等待锁的解除。
示例二:双重校验锁式单例模式
public class DoubleCheckedSingleton {
private static volatile DoubleCheckedSingleton instance;
private DoubleCheckedSingleton() {}
public static DoubleCheckedSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedSingleton();
}
}
}
return instance;
}
}
在这个示例中,我们使用双重校验锁的方式来保证线程的安全性和程序的性能。我们使用了一个volatile关键字来保证多线程下的可见性。在代码中使用了两个判断语句:if (instance == null)
来防止多次实例化对象和synchronized
关键字来保证线程安全性。如果实例化对象成功了,则直接返回这个对象实例,否则进入同步锁区域,再次确认instance是否为null,如果还是null则开始创建该实例。相对于懒汉式单例模式,双重校验锁式单例模式避免了同步锁的性能问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程之线程安全的单例模式 - Python技术站