Java 鎖

yunduan發表於2016-12-04
什麼是執行緒安全?
當多個執行緒訪問一個物件時,如果不用考慮這些執行緒在執行時環境的排程和交替執行,也不需要進行額外的同步,或者在呼叫方進行任何其他的協調操作,呼叫這個物件的行為都可以獲得正確的結果,那這個物件就是執行緒安全的。程式碼本省封裝了所有必要的正確性保障手段(互斥同步等),令呼叫者無需關心多執行緒的問題,更無需自己實現任何措施來保證多執行緒的正確呼叫。

如何來實現執行緒安全?
我們應用最多的就是互斥鎖;
java的互斥鎖的主要有synchronized,和JUC 中的lock兩種;

加鎖的原理是
物件上有一個是否加鎖的標誌位和鎖計數器,一個執行緒訪問了一個鎖住的程式碼後,獲取鎖,這時候會修改加鎖標誌位為“已加鎖”,鎖計數器=1;同一個執行緒訪問多個synchronized程式碼是不需要重複獲取鎖的,也就是說同一個執行緒是不會出現死鎖的問題。只是 鎖計數器 = 鎖計數器+1;當鎖計數器=0時,會釋放該物件的鎖。如果synchronized修飾的是一個靜態方法或class,這種情況是類鎖。而區別於前面的物件鎖了。

synchronized 主要用來修飾方法,或程式碼塊,在{}中的程式碼是需要獲取鎖以後才能訪問的,
synchronized的加鎖和鎖的釋放是有jvm管理的,不需要我們程式碼控制。

ReentrantLock的高階特性有那幾個?

1、等待可中斷,當持有鎖的執行緒長期不釋放的時候,正在等待的執行緒可以選擇放棄等待,改為處理其他事情;

2、可以實現公平鎖,公平鎖指多個執行緒在等待同一個鎖時,必須按照申請鎖的順序依次獲得鎖,synchronized是非公平鎖,ReentrantLock預設也是非公平的,只不過可以透過建構函式來制定實現公平鎖;

3、鎖繫結多個條件,ReentrantLock物件可以同時繫結多個Condition物件,在synchronized中,鎖物件的wait/notify/notifyall方法可以實現一個隱含的條件,如果要多一個條件關聯的時候,就需要額外的增加一個鎖;

關於鎖的幾個使用建議?

1、使用併發包中的類,併發包中的類大多數採用了lock-free等演算法,減少了多執行緒情況下的資源的鎖競爭,因此對於執行緒間的共享操作的資源而言,應儘量使用併發包中的類來實現;

2、儘可能少用鎖,沒必要用鎖的地方就不要用了;

3、拆分鎖,即把獨佔鎖拆分為多把鎖(這個不一定完全適用);

相關文章