利用Lazy简化单例模式的编写

相信大部分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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值