av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

什么是可中斷鎖?有什么用?怎么實(shí)現(xiàn)?

作者 | 王磊

創(chuàng)新互聯(lián)公司專(zhuān)注于建寧企業(yè)網(wǎng)站建設(shè),自適應(yīng)網(wǎng)站建設(shè),商城網(wǎng)站定制開(kāi)發(fā)。建寧網(wǎng)站建設(shè)公司,為建寧等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站設(shè)計(jì),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)公司專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)

來(lái)源 | Java中文社群(ID:javacn666)

轉(zhuǎn)載請(qǐng)聯(lián)系授權(quán)(微信ID:GG_Stone

在 Java 中有兩種鎖,一種是內(nèi)置鎖 synchronized,一種是顯示鎖 Lock,其中 Lock 鎖是可中斷鎖,而 synchronized 則為不可中斷鎖。

所謂的中斷鎖指的是鎖在執(zhí)行時(shí)可被中斷,也就是在執(zhí)行時(shí)可以接收 interrupt 的通知,從而中斷鎖執(zhí)行。

PS:默認(rèn)情況下 Lock 也是不可中斷鎖,但是可以通過(guò)特殊的“手段”,可以讓其變?yōu)榭芍袛噫i,接下來(lái)我們一起來(lái)看。

為什么需要可中斷鎖?

不可中斷鎖的問(wèn)題是,當(dāng)出現(xiàn)“異?!睍r(shí),只能一直阻塞等待,別無(wú)其他辦法,比如下面這個(gè)程序。下面的這個(gè)程序中有兩個(gè)線(xiàn)程,其中線(xiàn)程 1 先獲取到鎖資源執(zhí)行相應(yīng)代碼,而線(xiàn)程 2 在 0.5s 之后開(kāi)始嘗試獲取鎖資源,但線(xiàn)程 1 執(zhí)行時(shí)忘記釋放鎖了,這就造成線(xiàn)程 2 一直阻塞等待的情況,實(shí)現(xiàn)代碼如下:

 
 
 
 
  1. import java.util.concurrent.locks.Lock; 
  2. import java.util.concurrent.locks.ReentrantLock; 
  3.  
  4. publicclass InterruptiblyExample { 
  5.     public static void main(String[] args) { 
  6.         Lock lock = new ReentrantLock(); 
  7.  
  8.         // 創(chuàng)建線(xiàn)程 1 
  9.         Thread t1 = new Thread(new Runnable() { 
  10.             @Override 
  11.             public void run() { 
  12.                 lock.lock(); 
  13.                 System.out.println("線(xiàn)程 1:獲取到鎖."); 
  14.                 // 線(xiàn)程 1 未釋放鎖 
  15.             } 
  16.         }); 
  17.         t1.start(); 
  18.  
  19.         // 創(chuàng)建線(xiàn)程 2 
  20.         Thread t2 = new Thread(new Runnable() { 
  21.             @Override 
  22.             public void run() { 
  23.                 // 先休眠 0.5s,讓線(xiàn)程 1 先執(zhí)行 
  24.                 try { 
  25.                     Thread.sleep(500); 
  26.                 } catch (InterruptedException e) { 
  27.                     e.printStackTrace(); 
  28.                 } 
  29.                 // 獲取鎖 
  30.                 System.out.println("線(xiàn)程 2:等待獲取鎖."); 
  31.                 lock.lock(); 
  32.                 try { 
  33.                     System.out.println("線(xiàn)程 2:獲取鎖成功."); 
  34.                 } finally { 
  35.                     lock.unlock(); 
  36.                 } 
  37.             } 
  38.         }); 
  39.         t2.start(); 
  40.     } 

以上代碼執(zhí)行的結(jié)果如下:

從上述結(jié)果可以看出,此時(shí)線(xiàn)程 2 在等待獲取鎖的操作,然而經(jīng)歷了 N 久之后...再次查看結(jié)果,依然是熟悉的畫(huà)面:

線(xiàn)程 2 還在阻塞等待獲取線(xiàn)程 1 釋放鎖資源,此時(shí)的線(xiàn)程 2 除了等之外,并無(wú)其他方法。

并且,但我們熟練的拿出了 JConsole,試圖得到一個(gè)死鎖的具體信息時(shí),卻得到了這樣的結(jié)果:

并沒(méi)有檢測(cè)到任何死鎖信息,從上圖我們可以看出,當(dāng)只有一個(gè)鎖資源的時(shí)候,系統(tǒng)并不會(huì)把這種情況判定為死鎖,當(dāng)然也沒(méi)有阻塞等待的具體信息嘍,此時(shí)只剩下線(xiàn)程 2 孤單地等待著它的“鎖兒”。

使用中斷鎖

然而,中斷鎖的出現(xiàn),就可以打破這一僵局,它可以在等待一定時(shí)間之后,主動(dòng)的中斷線(xiàn)程 2,以解決線(xiàn)程阻塞等待的問(wèn)題。

中斷鎖的核心實(shí)現(xiàn)代碼是 lock.lockInterruptibly() 方法,它和 lock.lock() 方法作用類(lèi)似,只不過(guò)使用 lockInterruptibly 方法可以?xún)?yōu)先接收中斷的請(qǐng)求,中斷鎖的具體實(shí)現(xiàn)如下:

 
 
 
 
  1. import java.util.concurrent.locks.Lock; 
  2. import java.util.concurrent.locks.ReentrantLock; 
  3.  
  4. publicclass InterruptiblyExample { 
  5.     public static void main(String[] args) throws InterruptedException { 
  6.         Lock lock = new ReentrantLock(); 
  7.  
  8.         // 創(chuàng)建線(xiàn)程 1 
  9.         Thread t1 = new Thread(new Runnable() { 
  10.             @Override 
  11.             public void run() { 
  12.                 try { 
  13.                     // 加鎖操作 
  14.                     lock.lock(); 
  15.                     System.out.println("線(xiàn)程 1:獲取到鎖."); 
  16.                 } catch (InterruptedException e) { 
  17.                     e.printStackTrace(); 
  18.                 } 
  19.                 // 線(xiàn)程 1 未釋放鎖 
  20.             } 
  21.         }); 
  22.         t1.start(); 
  23.  
  24.         // 創(chuàng)建線(xiàn)程 2 
  25.         Thread t2 = new Thread(new Runnable() { 
  26.             @Override 
  27.             public void run() { 
  28.                 // 先休眠 0.5s,讓線(xiàn)程 1 先執(zhí)行 
  29.                 try { 
  30.                     Thread.sleep(500); 
  31.                 } catch (InterruptedException e) { 
  32.                     e.printStackTrace(); 
  33.                 } 
  34.                 // 獲取鎖 
  35.                 try { 
  36.                     System.out.println("線(xiàn)程 2:嘗試獲取鎖."); 
  37.                     lock.lockInterruptibly(); // 可中斷鎖 
  38.                     System.out.println("線(xiàn)程 2:獲取鎖成功."); 
  39.                 } catch (InterruptedException e) { 
  40.                     System.out.println("線(xiàn)程 2:執(zhí)行已被中斷."); 
  41.                 } 
  42.             } 
  43.         }); 
  44.         t2.start(); 
  45.  
  46.         // 等待 2s 后,終止線(xiàn)程 2 
  47.         Thread.sleep(2000); 
  48.         if (t2.isAlive()) { // 線(xiàn)程 2 還在執(zhí)行 
  49.             System.out.println("執(zhí)行線(xiàn)程的中斷."); 
  50.             t2.interrupt(); 
  51.         } else { 
  52.             System.out.println("線(xiàn)程 2:執(zhí)行完成."); 
  53.         } 
  54.     } 

以上代碼執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,當(dāng)我們使用了 lockInterruptibly 方法就可以在一段時(shí)間之后,判斷它是否還在阻塞等待,如果結(jié)果為真,就可以直接將他中斷,如上圖效果所示。

但當(dāng)我們嘗試將 lockInterruptibly 方法換成 lock 方法之后(其他代碼都不變),執(zhí)行的結(jié)果就完全不一樣了,實(shí)現(xiàn)代碼如下:

 
 
 
 
  1. import java.util.concurrent.locks.Lock; 
  2. import java.util.concurrent.locks.ReentrantLock; 
  3.  
  4. publicclass InterruptiblyExample { 
  5.     public static void main(String[] args) throws InterruptedException { 
  6.         Lock lock = new ReentrantLock(); 
  7.  
  8.         // 創(chuàng)建線(xiàn)程 1 
  9.         Thread t1 = new Thread(new Runnable() { 
  10.             @Override 
  11.             public void run() { 
  12.                 try { 
  13.                     // 加鎖操作 
  14.                     lock.lockInterruptibly(); 
  15.                     System.out.println("線(xiàn)程 1:獲取到鎖."); 
  16.                 } catch (InterruptedException e) { 
  17.                     e.printStackTrace(); 
  18.                 } 
  19.                 // 線(xiàn)程 1 未釋放鎖 
  20.             } 
  21.         }); 
  22.         t1.start(); 
  23.  
  24.         // 創(chuàng)建線(xiàn)程 2 
  25.         Thread t2 = new Thread(new Runnable() { 
  26.             @Override 
  27.             public void run() { 
  28.                 // 先休眠 0.5s,讓線(xiàn)程 1 先執(zhí)行 
  29.                 try { 
  30.                     Thread.sleep(500); 
  31.                 } catch (InterruptedException e) { 
  32.                     e.printStackTrace(); 
  33.                 } 
  34.                 // 獲取鎖 
  35.                 try { 
  36.                     System.out.println("線(xiàn)程 2:嘗試獲取鎖."); 
  37.                     lock.lock(); 
  38.                     System.out.println("線(xiàn)程 2:獲取鎖成功."); 
  39.                 } catch (Exception e) { 
  40.                     System.out.println("線(xiàn)程 2:執(zhí)行已被中斷."); 
  41.                 } 
  42.             } 
  43.         }); 
  44.         t2.start(); 
  45.  
  46.         // 等待 2s 后,終止線(xiàn)程 2 
  47.         Thread.sleep(2000); 
  48.         if (t2.isAlive()) { // 線(xiàn)程 2 還在執(zhí)行 
  49.             System.out.println("執(zhí)行線(xiàn)程的中斷."); 
  50.             t2.interrupt(); 
  51.         } else { 
  52.             System.out.println("線(xiàn)程 2:執(zhí)行完成."); 
  53.         } 
  54.     } 

以上程序執(zhí)行結(jié)果如下:

從上圖可以看出,當(dāng)使用 lock 方法時(shí),即使調(diào)用了 interrupt 方法依然不能將線(xiàn)程 2 進(jìn)行中斷。

總結(jié)

本文介紹了中斷鎖的實(shí)現(xiàn),通過(guò)顯示鎖 Lock 的 lockInterruptibly 方法來(lái)完成,它和 lock 方法作用類(lèi)似,但 lockInterruptibly 可以?xún)?yōu)先接收到中斷的通知,而 lock 方法只能“死等”鎖資源的釋放,同時(shí)這兩個(gè)方法的區(qū)別也是常見(jiàn)的面試題,希望本文對(duì)你有用。


當(dāng)前題目:什么是可中斷鎖?有什么用?怎么實(shí)現(xiàn)?
URL地址:http://uogjgqi.cn/article/djgjipj.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流