Java函数实现单例模式,如何做到线程安全?
发布时间:2023-07-06 12:03:30
在Java中,实现线程安全的单例模式可以通过以下几种方式:
1. 饿汉式(早期初始化):
这种方式下,单例对象在类加载的时候就创建好了,所以是线程安全的。实现方式很简单,就是在类中定义一个私有的静态成员变量,并在类加载时就初始化这个成员变量。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
2. 懒汉式(延迟初始化):
这种方式下,单例对象在 次使用时才创建,通过使用同步锁来保证多个线程安全地访问。
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
上述方式虽然实现了线程安全,但每次调用getInstance()方法时都需要进行同步,会造成不必要的性能开销。
3. 双重检验锁:
该方式在懒汉式的基础上进行了改进,只在 次创建实例时进行同步,之后的调用就无需再进行同步。在方法内部使用两次判空的原因是: 次判空是为了避免不必要的同步,第二次判空是为了确定只有一个线程能够创建实例。
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
4. 静态内部类:
这种方式通过使用静态内部类来实现延迟初始化,由于静态内部类只会在 次被使用时才进行加载,且类加载过程是线程安全的,所以是线程安全的。
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
需要注意的是,以上提到的方式都可以实现线程安全的单例模式,但并不是所有的方式都适用于所有的场景,需要根据具体的需求选择合适的实现方式。
