相信大部分Java开发者在工作中都用到过单例模式(即便这个设计模式并不是一个让人称道的模式),对于饿汉式的编写还好,双检锁懒汉式的编写就比较繁琐了,比如:
class SingletonDemo {
private SingletonDemo() {
}
private static volatile SingletonDemo instance;
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo.class) {
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
}
虽然这段代码比较短,但如果项目中用的比较多的时候,多次编写一样的代码也是一件很郁闷的事,而且多次编写只会增加出错的可能。下面就提供一种非常简单的方法来简化这个代码。
因为单例模式要求私有的instance
静态成员只被初始化一次,这恰好符合惰性求值的特点,所以我们可以利用Lazy
(实现代码见最下方)来完成这一点。先来看修改后的情况:
class SingletonDemo {
private SingletonDemo() {
}
private static final Lazy<SingletonDemo> instance = Lazy.from(SingletonDemo::new);
public static SingletonDemo getInstance() {
return instance.get();
}
}
这样一来,就不需要每次编写双检锁和if
判断了,代码看上去和饿汉式差不多。(毕竟懒汉式和饿汉式差的就是lazy嘛)
下面是Lazy
类的实现:
import java.util.function.Supplier;
public class Lazy<T> implements Supplier<T> {
private final Supplier<T> supplier;
private T value;
private volatile boolean isEvaluated = false;
public static <T> Lazy<T> from(Supplier<T> supplier) {
return new Lazy<>(supplier);
}
public static <T> Lazy<T> lazy(Supplier<T> supplier) {
return from(supplier);
}
private Lazy(Supplier<T> supplier) {
this.supplier = supplier;
}
@Override
public T get() {
if (!isEvaluated) {
synchronized (this) {
if (!isEvaluated) {
value = supplier.get();
isEvaluated = true;
}
}
}
return value;
}
}