為了性能與使用的場景,Java實作鎖的方式有非常多。而關于鎖主要的實作包含synchronized關鍵字、AQS架構下的鎖,其中的實作都離不開以下的政策。
悲觀鎖與樂觀鎖
- 樂觀鎖。樂觀的想法,認為并發讀多寫少。每次操作的時候都不上鎖,直到更新的時候才通過CAS判斷更新。對于AQS架構下的鎖,初始就是樂觀鎖,若CAS失敗則轉化為悲觀鎖。
- 悲觀鎖。悲觀的想法,認為并發寫多讀少。每次操作資料都上鎖,即使别人想讀也要先獲得鎖才能讀。對于1.6以前的synchronized關鍵字,則是悲觀鎖的實作之一。
CAS無鎖算法
全稱為 Compare and Swap。CAS有三個操作數,記憶體值V,舊預期值(已獲得的舊資料)A,修改新值B。當且僅當V與A的值相同(compare),才能把V替換為B(Swap)。其中Java中記憶體值可以通過volatile關鍵字辨別擷取,該關鍵詞可以使變量對所有線程實時可見。
CAS算法在鎖的應用非常廣泛,java中concurrent包的高性能都是基于這個算法,可以說沒有CAS,并發包的高性能也就不存在了。
重量級鎖
悲觀鎖的一種。互斥使代碼執行可以同步,但這種方式成本比較高,涉及到作業系統的調用阻塞,會造成一些系統資源的浪費。1.6以前,在Java中的即是螢幕鎖,把.java檔案程式設計成.class檔案後能看到synchronized關鍵字就是通過monitorenter和monitorexit這個兩個位元組碼指令來實作的。