你見過這樣的單例模式嗎

并發的學習與使用
通過單例模式理解synchronized,volatile
上兩篇主要是常見的關于并發的一些知識,本篇將介紹一些自己平常不常用的一些并發相關的內容。
單例模式的一種新的方式
最近在讀RxJava的源碼時,見到了一種新的單例模式,可能是自己見識太少,之前對這種方式真的沒見過,也可以說聞所未聞。由此引發了一些對Atomic**相關原子類的思考的研究,先看代碼:

public class Singleton {    
    private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();    
    private Singleton (){}    
    public static  Singleton getInstance() {            
        for (;;) {            
            Singleton current = INSTANCE.get();                 
            if (current != null) {                
                return current;            
            }            
            current = new Singleton();            
            if (INSTANCE.compareAndSet(null, current)) {                
                return current;           
           }       
     }    
  }
}

先看下AtomicReference的源碼:

只貼出主要涉及部分.png

AtomicReference是作用是對"對象"進行原子操作。通過源碼可以看出,它是通過"volatile"和"Unsafe提供的CAS(比較與交換,Compare and swap,是一種有名的無鎖算法函數)實現原子操作。

  • current是volatile類型。這保證了:當某線程修改value的值時,其他線程看到的value值都是最新的value值,即修改之后的volatile的值。
  • 通過CAS設置value。這保證了:當某線程池通過CAS函數(如compareAndSet函數)設置value時,它的操作是原子的,即線程在操作value時不會被中斷。CAS是一種無阻塞的鎖,采用不斷比較設值的方式來避免并發問題,不會有鎖的等待和上下文切換問題,性能消耗較小。

如果當前值 == 預期值,則以原子方式將該值設置為給定的更新值。
這種方式既能夠保證延遲加載又能保證原子性及實例的唯一性,代碼也相對比較簡潔。
通過并發的學習與使用,線程的阻塞和上下文的切換會帶來一定的性能開銷,尤其在高并發的環境下。
而原子變量可以避免優先級倒置和死鎖等危險,競爭比較便宜,協調發生在更細的粒度級別,允許更高程度的并行機制等等

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容