JAVA Lock 接口

在jdk1.5之后伸眶,并發(fā)包中新增了Lock接口(以及相關(guān)實(shí)現(xiàn)類)用來實(shí)現(xiàn)鎖功能,Lock接口提供了與synchronized關(guān)鍵字類似的同步功能敷扫,但需要在使用時手動獲取鎖和釋放鎖哀蘑。雖然Lock接口沒有synchronized關(guān)鍵字自動獲取和釋放鎖那么便捷,但Lock接口卻具有了鎖的可操作性葵第,可中斷獲取以及超時獲取鎖等多種非常實(shí)用的同步特性绘迁,除此之外Lock接口還有兩個非常強(qiáng)大的實(shí)現(xiàn)類重入鎖和讀寫鎖。

Lock接口的使用

Lock lock  = new ReentrantLock();
lock.lock();
try{
//可能會出現(xiàn)線程安全的操作
}finally{
//一定在finally中釋放鎖
//也不能把獲取鎖在try中進(jìn)行卒密,因?yàn)橛锌赡茉讷@取鎖的時候拋出異常
  lock.ublock();
}

---Lock接口與synchronized關(guān)鍵字的區(qū)別:
? Lock接口可以嘗試非阻塞地獲取鎖 當(dāng)前線程嘗試獲取鎖缀台。如果這一時刻鎖沒有被其他線程獲取到,則成功獲取并持有鎖哮奇。
*Lock接口能被中斷地獲取鎖 與synchronized不同膛腐,獲取到鎖的線程能夠響應(yīng)中斷,當(dāng)獲取到的鎖的線程被中斷時鼎俘,中斷異常將會被拋出哲身,同時鎖會被釋放。
? Lock接口在指定的截止時間之前獲取鎖而芥,如果截止時間到了依舊無法獲取鎖律罢,則返回。
Lock接口的API
? void lock() 獲取鎖,調(diào)用該方法當(dāng)前線程將會獲取鎖棍丐,當(dāng)鎖獲取后误辑,該方法將返回。
? void lockInterruptibly() throws InterruptedException 可中斷獲取鎖歌逢,與lock()方法不同之處在于該方法會響應(yīng)中斷巾钉,即在鎖的獲取過程中可以中斷當(dāng)前線程
? boolean tryLock() 嘗試非阻塞的獲取鎖,調(diào)用該方法立即返回秘案,true表示獲取到鎖
? boolean tryLock(long time,TimeUnit unit) throws InterruptedException 超時獲取鎖砰苍,以下情況會返回:時間內(nèi)獲取到了鎖潦匈,時間內(nèi)被中斷,時間到了沒有獲取到鎖赚导。
? void unlock() 釋放鎖
了解Lock接口最常用的實(shí)現(xiàn)ReentrantLock重入鎖
---ReentrantLock是Lock接口一種常見的實(shí)現(xiàn)茬缩,它是支持重進(jìn)入的鎖即表示該鎖能夠支持一個線程對資源的重復(fù)加鎖。該鎖還支持獲取鎖時的公平與非公平的選擇吼旧。
關(guān)于鎖的重進(jìn)入凰锡,其實(shí)synchronized關(guān)鍵字也支持。如前所述圈暗,synchronized關(guān)鍵字也是隱式的支持重進(jìn)入而對于ReentrantLock而言掂为,對于已經(jīng)獲取到鎖的線程,再次調(diào)用lock()方法時依然可以獲取鎖而不被阻塞员串。
理解了鎖的重進(jìn)入勇哗,現(xiàn)在解釋剛剛提到的公平獲取鎖與非公平獲取鎖。如果在絕對時間上寸齐,先對于鎖進(jìn)行獲取的請求一定先被滿足欲诺,那么這個鎖就是公平的,反之就是非公平的渺鹦。公平的獲取鎖也就是等待時間最久的線程優(yōu)先獲取到鎖瞧栗。ReentrantLock的構(gòu)造函數(shù)來控制是否為公平鎖。
---在第一次了解到公平鎖于非公平鎖的時候海铆,第一反應(yīng)是公平鎖的效率高,應(yīng)該使用公平鎖挣惰。但實(shí)際的情況是卧斟,非公平的鎖的效率遠(yuǎn)遠(yuǎn)大于公平鎖。
---了解Lock接口的實(shí)現(xiàn)類ReentrantReadWriteLock讀寫鎖
---前面提到的ReentrantLock是排他鎖憎茂,該鎖在同一時刻只允許一個線程來訪問珍语,而讀寫鎖在同一時刻允許可以有多個線程來訪問,但在寫線程訪問時竖幔,所有的讀線程和其他寫線程被阻塞板乙。讀寫鎖維護(hù)了一對鎖,一個讀鎖和一個寫鎖拳氢,通過讀寫鎖分離募逞,使得并發(fā)性相比一般的排他鎖有了很大的提升。
---讀寫鎖除了使用在寫操作happends-before與讀操作以及并發(fā)性的提升之外馋评,讀寫鎖也能夠簡化讀寫交互場景的編程方式放接。假設(shè)在程序中定義一個共享的用作緩存數(shù)據(jù)結(jié)構(gòu),它的大部分時間提供讀服務(wù)(查詢留特,搜索等)而寫操作較少纠脾,但寫操作之后需要立即對后續(xù)的讀操作可見玛瘸。在沒有讀寫鎖之前,實(shí)現(xiàn)這個功能需要使用等待通知機(jī)制苟蹈。無論使用那種方式糊渊,目的都是為了寫操作立即可見于讀操作而避免臟讀。但使用讀寫鎖卻比等待通知簡單明了多了慧脱。
---一般情況下渺绒,讀寫鎖性能優(yōu)于排他鎖。它能提供更好的并發(fā)性和吞吐量磷瘤。
ReentrantReadWriteLock讀寫鎖的幾個特性:
? 公平選擇性
? 重進(jìn)入
? 鎖降級
讀寫鎖的示例:緩存

public class Cache{
  static Map<String,Object> map = new HashMap<String,Object>();
  static ReentrantReadWriteLock  rwl = new ReentrantReadWriteLock();
  static Lock rLock = rwl.readLock();
  static Lock wLock = rwl.writeLock();
  //獲取一個key對應(yīng)的value
  public static final Object get(String key){
  r.lock();
  try{
   return map.get(key);
   }finally{
    r.unlock();
    }
  }
  //設(shè)置key對應(yīng)的value并返回舊的value
  public static fianl Object put(String key,Object value){
  w.lock();
  try{
   return map.put(key,value);
   }final{
   w.unlock();
    }
  }
  //清空緩存
  public static fianl void clear(){
  w.lock();
  try{
     map.clear();
   } finally{
    w.unlock();
    }
  }
}

---上述緩存示例中芒篷,我們使用了一個非線程安全的HashMap作為緩存的時候然后使用讀寫鎖來保證線程安全。Cache使用讀寫鎖提升讀操作的并發(fā)性采缚,也保證每次寫操作對讀操作的及時可見性针炉,同時簡化了編程方式。
讀寫鎖的鎖降級
---鎖降級是指寫鎖降級成為讀鎖扳抽。如果當(dāng)前線程持有寫鎖篡帕,然后將其釋放再獲取讀鎖的過程不能稱為鎖降級。鎖降級指的在持有寫鎖的時候再獲取讀鎖,獲取到讀鎖后釋放之前寫鎖的過程稱為鎖釋放贸呢。
---鎖降級在某些情況下是非常必要的镰烧,主要是為了保證數(shù)據(jù)的可見性。如果當(dāng)前線程不獲取讀鎖而直接釋放寫鎖楞陷,假設(shè)此時另外一個線程獲取了寫鎖并修改了數(shù)據(jù)怔鳖。那么當(dāng)前線程無法感知該線程的數(shù)據(jù)更新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末固蛾,一起剝皮案震驚了整個濱河市结执,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌艾凯,老刑警劉巖献幔,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異趾诗,居然都是意外死亡蜡感,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門恃泪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來郑兴,“玉大人,你說我怎么就攤上這事贝乎¤颈剩” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵糕非,是天一觀的道長蒙具。 經(jīng)常有香客問我球榆,道長,這世上最難降的妖魔是什么禁筏? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任持钉,我火速辦了婚禮,結(jié)果婚禮上篱昔,老公的妹妹穿的比我還像新娘每强。我一直安慰自己,他們只是感情好州刽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布空执。 她就那樣靜靜地躺著,像睡著了一般穗椅。 火紅的嫁衣襯著肌膚如雪辨绊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天匹表,我揣著相機(jī)與錄音门坷,去河邊找鬼。 笑死袍镀,一個胖子當(dāng)著我的面吹牛默蚌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苇羡,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼绸吸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了设江?” 一聲冷哼從身側(cè)響起惯裕,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绣硝,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撑刺,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹉胖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了够傍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甫菠。...
    茶點(diǎn)故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖冕屯,靈堂內(nèi)的尸體忽然破棺而出寂诱,到底是詐尸還是另有隱情,我是刑警寧澤安聘,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布痰洒,位于F島的核電站瓢棒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏丘喻。R本人自食惡果不足惜脯宿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泉粉。 院中可真熱鬧连霉,春花似錦、人聲如沸嗡靡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讨彼。三九已至歉井,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間点骑,已是汗流浹背酣难。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留黑滴,地道東北人憨募。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像袁辈,于是被迫代替她去往敵國和親菜谣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容