写一个线程安全高效的懒加载单例
时间: 2023-06-10 10:09:02 浏览: 40
好的,以下是一个线程安全高效的懒加载单例示例:
```java
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
```
这个示例的关键点是使用了双重检查锁定(Double-Checked Locking)来确保线程安全和高效。在第一次调用 `getInstance()` 方法时,如果 `instance` 为 `null`,则多个线程可以进入同步块,但只有一个线程可以实例化 `Singleton` 对象。一旦 `instance` 被实例化,所有进入同步块的线程将不再创建新的实例,而是返回已经创建的实例。
另外,`volatile` 关键字确保了在多线程环境下对 `instance` 变量的可见性,避免了因为指令重排而导致的线程不安全的问题。
相关问题
线程安全高效的懒加载单例的第一个if判断可不可以不写
在懒加载单例模式中,第一个if判断通常用于判断实例是否已经被创建,如果已经被创建则直接返回实例,否则才会创建实例。如果不加第一个if判断,每次调用getInstance()方法时都会创建一个新的实例,这样就违背了单例模式的初衷。
在多线程环境下,如果不加锁的情况下同时有多个线程访问getInstance()方法,可能会导致创建多个实例的情况发生。因此,第一个if判断是必须的,用于保证只创建一个实例。
至于第一个if判断是否可以不写,如果你确定你的单例模式只会在单线程环境下使用,那么可以不写。但是在多线程环境下,为了保证线程安全,第一个if判断是必不可少的。
写一个线程安全的懒汉式单例模式
好的,以下是一个使用双重检查锁定方式实现的线程安全的懒汉式单例模式的示例代码:
```java
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;
}
}
```
在该例子中,我们使用 `private static volatile` 关键字定义了一个静态的 `instance` 对象,`volatile` 关键字可以保证多线程之间的可见性。在 `getInstance()` 方法中,我们通过 `if (instance == null)` 判断该对象是否为 `null`,如果为 `null` 则进入同步代码块,在同步代码块中再次判断 `instance` 是否为 `null`,如果为 `null` 则创建一个新的实例对象并赋值给 `instance`,然后返回该实例对象。由于使用了双重检查锁定方式,因此可以保证在多线程环境下只会创建一个实例对象。
还有一种实现方式是使用静态内部类,以下是使用静态内部类实现的线程安全的懒汉式单例模式的示例代码:
```java
public class Singleton {
private Singleton() {
// 私有化构造方法,防止外部实例化对象
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
```
在该例子中,我们使用静态内部类 `SingletonHolder` 来创建实例对象,由于静态内部类只有在被引用时才会被加载,因此可以保证在多线程环境下只会创建一个实例对象。在 `getInstance()` 方法中,我们直接返回 `SingletonHolder.INSTANCE` 即可获取实例对象。