鎖是多線程并發問題中的重要組成,接着上一篇文章,今天就簡單總結一下Java中各種鎖如何分類。
Java中鎖分為以下幾種:
- 樂觀鎖、悲觀鎖
- 獨享鎖、共享鎖
- 公平鎖、非公平鎖
- 互斥鎖、讀寫鎖
- 可重入鎖
- 分段鎖
- 鎖更新(無鎖 -> 偏向鎖 -> 輕量級鎖 -> 重量級鎖) JDK1.6
這些鎖的分類并不全是指鎖的狀态,有的指鎖的特性,有的指鎖的設計,下面總結的内容是對每個鎖的名詞進行一定的解釋。
1、樂觀鎖 & 悲觀鎖
兩種鎖隻是一種概念
樂觀鎖:樂觀鎖認為一個線程去拿資料的時候不會有其他線程對資料進行更改,是以不會上鎖。
實作方式:CAS機制、版本号機制
悲觀鎖:悲觀鎖認為一個線程去拿資料時一定會有其他線程對資料進行更改。是以一個線程在拿資料的時候都會順便加鎖,這樣别的線程此時想拿這個資料就會阻塞。比如Java裡面的synchronized關鍵字的實作就是悲觀鎖。實作方式:就是加鎖。
2、獨享鎖 & 共享鎖
獨享鎖:該鎖一次隻能被一個線程所持有
共享鎖:該鎖可以被多個線程所持有
舉例:
synchronized是獨享鎖;
可重入鎖ReentrantLock是獨享鎖;
讀寫鎖ReentrantReadWriteLock中的讀鎖ReadLock是共享鎖,寫鎖WriteLock是獨享鎖。
獨享鎖與共享鎖通過AQS(AbstractQueuedSynchronizer)來實作的,通過實作不同的方法,來實作獨享或者共享。
3、互斥鎖 & 讀寫鎖
上面講的獨享鎖/共享鎖就是一種概念,互斥鎖/讀寫鎖是具體的實作。
互斥鎖的具體實作就是synchronized、ReentrantLock。ReentrantLock是JDK1.5的新特性,采用ReentrantLock可以完全替代替換synchronized傳統的鎖機制,更加靈活。
讀寫鎖的具體實作就是讀寫鎖ReadWriteLock。
4、可重入鎖
定義:對于同一個線程在外層方法擷取鎖的時候,在進入内層方法時也會自動擷取鎖。
優點:避免死鎖
舉例:ReentrantLock、synchronized
5、公平鎖 & 非公平鎖
公平鎖:多個線程互相競争時要排隊,多個線程按照申請鎖的順序來擷取鎖。
非公平鎖:多個線程互相競争時,先嘗試插隊,插隊失敗再排隊,比如:synchronized、ReentrantLock
6、分段鎖
分段鎖并不是具體的一種鎖,隻是一種鎖的設計。