首页 未命名正文

不使用synchronized和lock,如何实现一个线程安全的单例?(二)

如果不那么挑剔,可以使用枚举、静态内部类和饿汉模式来实现单例模式。见:不用synchronized和lock,如何实现线程安全的单例? 然而,上述 *** 也用于底层synchronized,那么有没有办法不用呢?synchronized和lock,如何实现线程安全的单例?

答案是肯定的,那就是CAS。关于CAS,我的博客里有一篇专门介绍他的文章,很多乐观锁都是基于的CAS实现。这里简单介绍一下,详情见 乐观锁的实现方式——CAS

CAS当多个线程尝试使用时,它是一种乐观的锁技术CAS同时,当更新相同的变量时,只有一个线程可以更新变量值,而其他线程失败,失败的线程不会被悬挂,但被告知在竞争中失败,并可以再次尝试。

在JDK1.5 中新增java.util.concurrent(J.U.C)就是建立在CAS以上。相对于对synchronized这种阻塞算法,CAS常见的实现是非阻塞算法。J.U.C性能有了很大的提高。

借助CAS(AtomicReference)实现单例模式:

  • publicclassSingleton{
  • privatestaticfinalAtomicReference<Singleton>INSTANCE=newAtomicReference<Singleton>();
  • privateSingleton(){}
  • publicstaticSingletongetInstance(){
  • for(;;){
  • Singletonsingleton=INSTANCE.get();
  • if(null!=singleton){
  • returnsingleton;
  • }
  • singleton=newSingleton();
  • if(INSTANCE.compareAndSet(null,singleton)){
  • returnsingleton;
  • }
  • }
  • }
  • }
  • 代码比较简单,稍微了解一下AtomicReference你可以理解原理。如果你不明白,建议去看看。了解这些CAS的实现。

    用CAS优点是不需要使用传统的锁机制来保证线程安全,CAS依靠底层硬件的实现,是一种基于忙等待算法的额外消耗,可以支持较大的并行性,而无需线程切换和阻塞。

    CAS一个重要的缺点是,如果等待不成功(一直在死循环中),它将是正确的CPU实施费用大。

    【本文是51CTO专栏作者Hollis原创文章,作者微信公众号Hollis(ID:hollischuang)】

    戳这里,看作者更好的文章

       
    版权声明

    本文仅代表作者观点,不代表本站立场。
    本文系作者授权发表,未经许可,不得转载。