日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
獨(dú)家報(bào)道lock.lock()寫在try外面?

本文轉(zhuǎn)載自微信公眾號(hào)「源碼興趣圈」,作者龍臺(tái)。轉(zhuǎn)載本文請(qǐng)聯(lián)系源碼興趣圈公眾號(hào)。

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),漢中企業(yè)網(wǎng)站建設(shè),漢中品牌網(wǎng)站建設(shè),網(wǎng)站定制,漢中網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,漢中網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

前言

面試官:小伙子,JUC 并發(fā)包下的可重入鎖 ReentrantLock 在代碼里實(shí)際使用過么

混子:用過,ReentrantLock 是 JDK 提供的可重入的鎖。提供對(duì) 共享資源的獨(dú)占訪問,一次只能有一個(gè)線程可以獲取該鎖

面試官:你覺得,ReentrantLock#lock 方法寫到 try 語句外面還是里面

混子:我......

面試官:我們不合適,你走吧

先給出結(jié)論,lock.lock() 最規(guī)范的寫法是寫到 try 語句的外面

lock.lock()

Oracle 文檔中在介紹鎖的使用時(shí)有一段代碼,我們以 ReentrantLock 舉例,代碼如下所示:

 
 
 
 
  1. ReentrantLock lock = new ReentrantLock(); 
  2. lock.lock(); 
  3. try { 
  4.     // access the resource protected by this lock 
  5. } finally { 
  6.     lock.unlock(); 

Q:為什么要把 lock.unlock() 放到 finally 語句塊?

A:為了保證當(dāng)前線程執(zhí)行過程中出現(xiàn)異常時(shí),鎖依然能被釋放掉,避免死鎖的產(chǎn)生

我們來改動(dòng)一下上面的代碼,看看會(huì)產(chǎn)生什么樣的影響

 
 
 
 
  1. ReentrantLock lock = new ReentrantLock(); 
  2. try { 
  3.     lock.lock(); 
  4.     // access the resource protected by this lock 
  5. } finally { 
  6.     lock.unlock(); 

看著沒問題呀,為啥文章開始不建議這么用?先說下可能會(huì)存在的問題

異常堆棧丟失

假設(shè)在 lock.lock 方法中加鎖異常(千萬不要杠),那么會(huì)進(jìn)入 finally 語句塊中進(jìn)行解鎖

繼續(xù)跟進(jìn),看一下 lock.unlock() 源碼中是如何處理的

lock.lock() 拋出異常有可能還沒獲取到鎖,那么 解鎖源碼中將當(dāng)前線程比較擁有鎖線程肯定是不相等的,所以會(huì)拋出 IMSE (IllegalMonitorStateException)異常

我重寫了 ReentrantLock 加鎖代碼的邏輯,在里面拋出了異常,一起看下會(huì)出現(xiàn)什么情況

 
 
 
 
  1. final void lock() { 
  2.     // 模擬加鎖未成功就拋出異常 
  3.     if (true) { 
  4.         throw new RuntimeException("報(bào)錯(cuò)啦?。。?); 
  5.     } 
  6.     if (compareAndSetState(0, 1)) 
  7.         setExclusiveOwnerThread(Thread.currentThread()); 
  8.     else 
  9.         acquire(1); 

根據(jù)下圖可以看出 加鎖時(shí)異常堆棧被 "吞掉了",悄無聲息的就沒了。當(dāng)然這只是舉例,但是誰能保證加鎖未成功時(shí)不會(huì)拋出異常呢

真實(shí)存在的 BUG

上面代碼示例中都是在 try 的第一行寫 lock,出現(xiàn)問題的可能性極低。這里給大家提供一個(gè)反面教材,千萬千萬不要有這種類似行為

示例代碼中把 lock 放到了 try 語句塊里,然后 lock 加鎖前面還有可能會(huì)產(chǎn)生異常的代碼,這種就涼了,誰用誰涼的那種

結(jié)尾

所以關(guān)于要不要把 lock.lock() 寫到 try 語句塊里,文章的結(jié)論是:

最好是把 lock.lock() 加鎖方法寫到 try 外面,這是一種規(guī)范,而不是強(qiáng)制

如果你非要寫到 try 里面,那么 請(qǐng)寫到 try 語句塊的第一行,或者 lock 加鎖方法前面不會(huì)存在可能出現(xiàn)異常的代碼

最后,如果你代碼中加鎖放到了 try 語句里,麻煩參考第 1 點(diǎn)


當(dāng)前標(biāo)題:獨(dú)家報(bào)道lock.lock()寫在try外面?
鏈接分享:http://m.5511xx.com/article/dphopep.html