1. 程式人生 > >java高併發鎖的3種實現

java高併發鎖的3種實現

中級技巧 - String.intern()

樂觀鎖不能很好解決大量寫衝突問題,但是如果很多場景下,鎖實際上只是針對某個使用者或者某個訂單。比如一個使用者必須先建立session,才能進行後面的操作。但是由於網路原因,建立使用者session的請求和後續請求幾乎同時達到,而並行執行緒可能會先處理後續請求。一般情況,需要對使用者sessionMap加鎖,比如上面的樂觀鎖。在這種場景下,可以講鎖限定到使用者本身上,即從原來的

lock.lock();

    int num=storage.get(key);

    storage.set(key,num+1);

lock.unlock();

更改為:

lock.lock(key);

    int num=storage.get(key);

    storage.set(key,num+1);

lock.unlock(key);

這個比較類似於資料庫表鎖和行鎖的概念,顯然行鎖的併發能力比表鎖高很多。

使用String.inter()是這種思路的一種具體實現。類 String 維護一個字串池。 當呼叫 intern 方法時,如果池已經包含一個等於此 String 物件的字串(該物件由 equals(Object) 方法確定),則返回池中的字串。可見,當String相同時,String.intern()總是返回同一個物件,因此就實現了對同一使用者加鎖。由於鎖的粒度侷限於具體使用者,使系統獲得了最大程度的併發。

Java程式碼  
  1. public void doSomeThing(String uid) {  
  2.    synchronized(uid.intern()) {  
  3.        // ...  
  4.    }  
  5. }  

CopyOnWriteMap?

既然說到了“類似於資料庫中的行鎖的概念”,就不得不提一下MVCC,Java中CopyOnWrite類實現了MVCC。Copy On Write是這樣一種機制。當我們讀取共享資料的時候,直接讀取,不需要同步。當我們修改資料的時候,我們就把當前資料Copy一份副本,然後在這個副本 上進行修改,完成之後,再用修改後的副本,替換掉原來的資料。這種方法就叫做Copy On Write。

但是,,,JDK並沒有提供CopyOnWriteMap,為什麼?下面有個很好的回答,那就是已經有了ConcurrentHashMap,為什麼還需要CopyOnWriteMap?

Fredrik Bromee 寫道 I guess this depends on your use case, but why would you need a CopyOnWriteMap when you already have a ConcurrentHashMap?

For a plain lookup table with many readers and only one or few updates it is a good fit.

Compared to a copy on write collection:

Read concurrency:

Equal to a copy on write collection. Several readers can retrieve elements from the map concurrently in a lock-free fashion.

Write concurrency:

Better concurrency than the copy on write collections that basically serialize updates (one update at a time). Using a concurrent hash map you have a good chance of doing several updates concurrently. If your hash keys are evenly distributed.

If you do want to have the effect of a copy on write map, you can always initialize a ConcurrentHashMap with a concurrency level of 1.