I、java中的鎖
1.1 什么是鎖
在計算機科學中,鎖(lock)與互斥(mutex)是一種同步機制,用於在許多線程執行時對資源的限制。
鎖通常需要硬件支持才可以有效實施。這種支持通常采用一個或多個原子指令,測試單個線程是否空閑。
1.2 鎖的三個概念
1. 鎖開銷:就是完成一個鎖可能額外耗費的資源,比如一個周期所需要的時間,內存空間。
2. 鎖競爭:一個線程或進程,要獲取另一個線程或進程所持有的鎖,邊會發生鎖競爭。鎖粒度越小,競爭的可能約小。
3. 死鎖:互相鎖住了
2 鎖的分類
2.1 獨享鎖/共享鎖
我私底下更想將其稱作為,開源鎖和閉源鎖。好了我覺得說到這里可以了。
2.2 互斥所/讀寫鎖
互斥所與讀寫鎖是狹義的說法。ReentrantLock就是互斥鎖也是獨享鎖,ReadWriteLock就是讀寫鎖也是共享鎖。
獨享與共享是被AQS(AbstractQueuedSynchronizer)定義的,
2.3 鎖升級/所降級
低於16位屬於寫鎖,高於16位屬於讀鎖
2.4 公平鎖/非公平鎖
公平鎖是按照線程的申請順序來進行的
非公平鎖是按照優先級進行,所以可能會差生飢餓現象
- RenntranLock 而言,默認是非公平,但也可以是公平鎖。通過構造函數指定。非公平鎖的吞吐量就是比公平鎖大。
- Synchronized也是一種非公平鎖。由於沒有AQS,所以 沒可能是公平鎖。
2.5 可重入鎖
也稱遞歸鎖,再同一線程的外層方法獲取鎖的時候,在進入內層方法自動獲取鎖。
ReentrantLock 和 Synchronized都是可重入鎖。可重入鎖一個好處是在一定程度上避免死鎖。
2.6 樂觀鎖/悲觀鎖
這兩個並沒有特定的類型,而是在看待並發之角度
悲觀鎖認為存在很多並發操作,采取加鎖措施,不加鎖一定會有問題。
樂觀鎖認為不存在很多並發操作就沒必要加鎖
2.7 分段鎖
分段鎖也是一種鎖設計,而不是特定的鎖。比如ConcuttenHashMap通過分段鎖來實現高並發
2.8 自旋鎖
自旋鎖是指試探資源的線程並不阻塞線程,而是采取循環的方式嘗試獲取線程,好處是減少上下文的切換,缺點是一直占用CPU
2.9 偏向鎖/輕量級鎖/重量級鎖
鎖 | 優點 | 缺點 | 適用場景 |
---|---|---|---|
偏向鎖 | 加鎖解鎖無需額外的消耗 | 如果存在鎖競爭,則存在鎖撤銷的消耗 | 只有一個線程訪問同步方法快的場景 |
輕量級鎖 | 競爭的線程不會存在阻塞,提高了程序的響應速度。 | 若始終得不到鎖競爭的線程使用自旋會消耗CPU | 同步塊執行的速度非常的快 |
重量級鎖 | 線程使用者不會自旋,不會消耗CPU | 線程阻塞,響應時間慢 | 吞吐量大 |