java 鎖 Lock 簡單學習
公平鎖和非公平鎖:區別在於是否會檢查執行緒佇列並且從執行緒佇列(雙端佇列)首獲取執行緒鎖;公平鎖-在每次獲取鎖時會檢查執行緒佇列是否還有執行緒,若有則從佇列首獲取執行緒並加鎖。非公平鎖-對於執行緒獲取鎖是隨機的,並不會去從佇列首去獲取鎖,新進執行緒有很大機率獲取到鎖。
Lock:java 提供的一種鎖區別於JVM提供的synchronized,並提供了多種獲取鎖的方式.簡單分為:ReentrantLock:可重入鎖、ReentrantLockReadWriteLock.readLock():讀鎖、ReentrantReadWriteLock.writeLock():寫鎖。
ReentrantLock:可重入鎖:意思是一個執行緒可重複的對一個資源進行加鎖。具有排他性,同一時間僅允許一個執行緒訪問資源。具體實現形式:
使用Lock與synchronized 使用區別在於Lock需要手動獲取並最終在finally中手動釋放鎖。synchronized:發生異常JVM會自動釋放鎖。
ReentrantReadWriteLock:讀寫鎖 :在同一時間允許多個執行緒訪問資源,但是在進行讀寫操作時僅允許一個執行緒操作,當一個執行緒在進行讀操作時其他讀執行緒阻塞,在進行寫操作時其他寫執行緒阻塞。從而提高併發量,實現了可重入、高併發、公平性以及鎖降級(持有讀鎖時再去獲取寫鎖,再釋放讀鎖)。具體實現:
Lock:重入鎖、讀寫鎖均提供了以下方法:
lock():獲取鎖。
trylock():只有在呼叫時它是空閒的,才獲得鎖。如果它是可用的,就獲得鎖,並立即返回值為true。如果鎖不可用,那麼這個方法將立即返回值為false。
tryLock(long time, TimeUnit unit):如果在給定時間內鎖時可用的,則獲取鎖,否則阻塞該執行緒,並處於休眠狀態。當出現以下三種情況時重新獲取:
鎖被當前執行緒獲取;
其他一些執行緒中斷當前執行緒,並支援鎖獲取的中斷;
指定的等待時間流逝
lockInterruptibly():獲得鎖,除非當前執行緒被阻斷。如果鎖不可用則執行緒禁用處於休眠狀態,直到出現以下情況:
鎖被當前執行緒獲取
其他一些執行緒中斷了當前執行緒,並且支援鎖獲取的中斷。
unlock():釋放鎖。
condition:執行緒間通訊同object中的wait(),notify()...等方法類似。不同在於condition:在多執行緒下可以根據指定情況操作執行緒,例如當啟動讀執行緒時,可以喚醒對應的寫執行緒(一個執行緒讀一個執行緒寫)。
ReentrantLock與ReentrantReadWriteLock:多執行緒時,執行緒對資源的訪問,以及併發效能問題區別。
ReentrantLock與synchronized:區別在於鎖的策略不同,synchronized使用悲觀的策略,當有一個執行緒嘗試獲取鎖,若未獲取到鎖,則執行緒阻塞。ReentrantLock:則使用樂觀的策略,當一個執行緒嘗試獲取鎖失敗時並不會立即阻塞該執行緒,而是不停的去嘗試獲取鎖,直到成功。阻塞執行緒再喚醒執行緒會消耗CPU降低效能。與valitale的區別在於valitale會增加資料的透明性,強制執行緒清空本地記憶體去主記憶體中讀取資料,改變變數強制重新整理到主記憶體