无锁的单例

本文介绍了一种利用CAS(CompareAndSwap)实现线程安全的单例模式的方法,避免了传统锁机制的使用,提高了并行度。通过实例演示了如何在多线程环境下保证单例的唯一性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何实现一个线程安全的单例,前提是不能加锁?

利用CAS(Compare And Swap)来实现无锁的单例。

用CAS的好处在于不需要使用传统的锁机制来保证线程安全,CAS是一种基于忙等待的算法,依赖底层硬件的实现,相对于锁它没有线程切换和阻塞的额外消耗,可以支持较大的并行度。

CAS的一个重要缺点在于如果忙等待一直执行不成功(一直在死循环中),会对CPU造成较大的执行开销。另外,如果N个线程同时执行到singleton = new Singleton();的时候,会有大量对象创建,很可能导致内存溢出。

public class Singleton {
    private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<>();

    private Singleton() {
    }

    public static Singleton getInstance() {
        for (; ; ) {
            Singleton singleton =  INSTANCE.get();
            if (null != singleton) {
                return singleton;
            }

            singleton = new Singleton();
            if (INSTANCE.compareAndSet(null, singleton)) {
                return singleton;
            }
        }
    }


    //test
    public static void main( String[] args ) throws Exception{
        Singleton singleton= Singleton.getInstance();
        Singleton singleton2= Singleton.getInstance();
        System.out.printf("singleton == singleton2 ? %s\n",singleton==singleton2);

        Test test=new Test();
        Test test2=new Test();
        ExecutorService executor= Executors.newFixedThreadPool(2);
        executor.execute(test);
        executor.execute(test2);
        Thread.sleep(1000);
        Singleton singleton3=test.getValue();
        Singleton singleton4=test2.getValue();
        System.out.printf("singleton3 == singleton4 ? %s\n",singleton3==singleton4);
        System.out.printf("singleton2 == singleton4 ? %s",singleton2==singleton4);
    }
}

class Test implements Runnable{

    private Singleton singleton;
    @Override
    public void run() {
        singleton=Singleton.getInstance();
    }

    public Singleton getValue(){
        return singleton;
    }

运行结果

singleton == singleton2 ? true
singleton3 == singleton4 ? true
singleton2 == singleton4 ? true

参考

https://www.jianshu.com/p/f3fae8658f13

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值