1. 程式人生 > >Java同步鎖------synchronized和lock

Java同步鎖------synchronized和lock

Synchronized

synchronized可用很好的解決多執行緒併發安全問題,但是在有些時候,他會使機器的效能降低,就比如在同步鎖內部發生IO阻塞,導致了其他想獲得鎖的執行緒不能獲得,一直阻塞在那裡,這樣大大降低的程式的執行效率。

經過總結synchronized有如下缺點:

(1)如果獲得鎖的執行緒發生了IO阻塞,或者呼叫了sleep方法,那麼這樣jvm是不會釋放鎖的(當執行緒發生異常,jvm才會讓執行緒自動釋放鎖),這麼一來,在阻塞過程中,cpu就空轉了,其他執行緒得不到鎖,這樣降低了機子的效能。

(2)如果多執行緒進行讀寫檔案時,讀操作和寫操作會發生衝突,寫操作和寫操作會發生衝突,讀操作和寫操作不會發生衝突,但是採用了synchronized,無論以上哪種情況,都會阻塞,我們知道,讀操作和讀操作是可用併發執行的,如果不阻塞可用提高效能。

綜合以上2個缺點:就有了lock。lock可以很好的解決以上問題,針對第一個,lock可以通過設定鎖的超時時間,超過設定時間就自動釋放鎖;針對第二點,lock就有相應的讀鎖和寫鎖。

Lock

lock是個介面,介面中有四個方法lock()、trylock()、trylock(long time, TimeUnit unit)、lockInterruptibly()來獲取鎖。

用unlock()來釋放鎖。

(1)lock是平常使用最多的一個方法,lock必須手動釋放,在發生異常的時候,jvm是不會取釋放鎖的,因此在用lock時候,要寫在try{}catch{}裡面,並且在finally{}中去釋放鎖,避免死鎖。

(2)trylock(),字面理解嘗試獲得鎖,當trylock獲得成功,就返回true,否則返回false,優點在於在拿不到鎖的時候,不會一直等待,而會繼續執行其他。

(3)trylock(long time, TimeUnit unit)和trylock()類似,就是多了引數,表示在指定時間仍然不能獲取鎖,那麼返回false,否則返回true。

(4)lockInterruptibly(),舉例:兩個執行緒A、B通過lock.lockInterruptibly()獲取鎖,A先獲得鎖,B只能等待,那麼B可以呼叫interrupt(),來中斷B的等待。

lock需要我們自己去實現,顯然不方便,那麼就有ReentrantLock實現類,意思是“可重入鎖”。

ReadWriteLock

ReadWriteLock是介面;其實現類是ReentrantReadWriteLock,主要有兩個方法:readLock()和writeLock()

注意:

不過要注意的是,如果有一個執行緒已經佔用了讀鎖,則此時其他執行緒如果要申請寫鎖,則申請寫鎖的執行緒會一直等待釋放讀鎖。如果有一個執行緒已經佔用了寫鎖,則此時其他執行緒如果申請寫鎖或者讀鎖,則申請的執行緒會一直等待釋放寫鎖。