Java多線程中的ReentrantLock可中斷鎖詳細(xì)解讀
ReentrantLock可中斷鎖
ReentrantLock中的lockInterruptibly()方法使得線程可以在被阻塞時(shí)響應(yīng)中斷,比如一個(gè)線程t1通過(guò)lockInterruptibly()方法獲取到一個(gè)可重入鎖,并執(zhí)行一個(gè)長(zhǎng)時(shí)間的任務(wù),另一個(gè)線程通過(guò)interrupt()方法就可以立刻打斷t1線程的執(zhí)行,來(lái)獲取t1持有的那個(gè)可重入鎖。而通過(guò)ReentrantLock的lock()方法或者Synchronized持有鎖的線程是不會(huì)響應(yīng)其他線程的interrupt()方法的,直到該方法主動(dòng)釋放鎖之后才會(huì)響應(yīng)interrupt()方法。下面看一個(gè)示例:
package com.teriste.thread; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; /** * 測(cè)試ReentrantLock可中斷鎖的效果 */ public class ThreadInteruptDemo { ReentrantLock lock1=new ReentrantLock(); ReentrantLock lock2=new ReentrantLock(); /** * ReentrantLock響應(yīng)中斷 * @throws Exception */ public void exeInterupt() throws Exception{ Thread t1=new Thread(new DemoThread(lock1,lock2)); Thread t2=new Thread(new DemoThread(lock2,lock1)); t1.start(); t2.start(); System.out.println(t1.getName()+"中斷"); //主線程睡眠1秒,避免線程t1直接響應(yīng)run方法中的睡眠中斷 Thread.sleep(1000); t1.interrupt(); //阻塞主線程,避免所有線程直接結(jié)束,影響死鎖效果 Thread.sleep(10000); } Object syn1=new Object(); Object syn2=new Object(); /** * Synchronized響應(yīng)中斷 * @throws Exception */ public void exeInteruptSyn() throws Exception{ Thread t1=new Thread(new DemoThread1(syn1,syn2)); Thread t2=new Thread(new DemoThread1(syn2,syn1)); t1.start(); t2.start(); System.out.println(t1.getName()+"中斷"); //主線程睡眠1秒,避免線程t1直接響應(yīng)run方法中的睡眠中斷 Thread.sleep(1000); t1.interrupt(); //阻塞主線程,避免所有線程直接結(jié)束,影響死鎖效果 Thread.sleep(100000); } /** * ReentrantLock實(shí)現(xiàn)死鎖 */ static class DemoThread implements Runnable{ ReentrantLock lock1; ReentrantLock lock2; public DemoThread(ReentrantLock lock1,ReentrantLock lock2){ this.lock1=lock1; this.lock2=lock2; } @Override public void run() { try { //可中斷的獲取鎖 lock1.lockInterruptibly(); //lock1.lock(); //睡眠200毫秒,保證兩個(gè)線程分別已經(jīng)獲取到兩個(gè)鎖,實(shí)現(xiàn)相互的鎖等待 TimeUnit.MILLISECONDS.sleep(200); //lock2.lock(); //可中斷的獲取鎖 lock2.lockInterruptibly(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock1.unlock(); lock2.unlock(); System.out.println("線程"+Thread.currentThread().getName()+"正常結(jié)束"); } } } /** * Synchronized實(shí)現(xiàn)死鎖 */ static class DemoThread1 implements Runnable{ Object lock1; Object lock2; public DemoThread1(Object lock1,Object lock2){ this.lock1=lock1; this.lock2=lock2; } @Override public void run() { try { synchronized (lock1){ //睡眠200毫秒,再獲取另一個(gè)鎖, //保證兩個(gè)線程分別已經(jīng)獲取到兩個(gè)鎖,實(shí)現(xiàn)相互的鎖等待 TimeUnit.MILLISECONDS.sleep(200); synchronized (lock2){ } } } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println("線程"+Thread.currentThread().getName()+"正常結(jié)束"); } } } }
測(cè)試代碼:
package com.teriste.thread; import org.junit.Test; public class ThreadInteruptDemoTest { /** * 測(cè)試ReentrantLock響應(yīng)中斷 * @throws Exception */ @Test public void exeInteruptTest() throws Exception{ ThreadInteruptDemo demo=new ThreadInteruptDemo(); demo.exeInterupt(); } /** * 測(cè)試Synchronized響應(yīng)中斷 * @throws Exception */ @Test public void exeInteruptSynTest() throws Exception{ ThreadInteruptDemo demo=new ThreadInteruptDemo(); demo.exeInteruptSyn(); } }
當(dāng)執(zhí)行exeInteruptTest()方法時(shí),可以看到線程t1立刻響應(yīng)了主線程的interrupt()方法:
當(dāng)執(zhí)行exeInteruptSynTest()方法時(shí),可以看到t0線程并沒(méi)有響應(yīng)中斷,兩個(gè)線程仍然處于相互等待鎖釋放的狀態(tài)。
到此這篇關(guān)于Java多線程中的ReentrantLock可中斷鎖詳細(xì)解讀的文章就介紹到這了,更多相關(guān)ReentrantLock可中斷鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中XML schema擴(kuò)展機(jī)制的深入講解
這篇文章主要給大家介紹了關(guān)于Spring中XML schema擴(kuò)展機(jī)制的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09Spring中的@EnableScheduling定時(shí)任務(wù)注解
這篇文章主要介紹了Spring中的@EnableScheduling注解,@EnableScheduling是 Spring Framework 提供的一個(gè)注解,用于啟用 Spring 的定時(shí)任務(wù)功能,通過(guò)使用這個(gè)注解,可以在 Spring 應(yīng)用程序中創(chuàng)建定時(shí)任務(wù),需要的朋友可以參考下2024-01-01分布式任務(wù)調(diào)度xxl-job問(wèn)題解決
這篇文章主要為大家介紹了分布式任務(wù)調(diào)度xxl-job的問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多多多進(jìn)步,早日升職加薪2022-03-03Spring6當(dāng)中獲取Bean的四種方式小結(jié)
Spring 為Bean 的獲取提供了多種方式,通常包括4種方式,(也就是說(shuō)在Spring中為Bean對(duì)象的創(chuàng)建準(zhǔn)備了多種方案,目的是:更加靈活),本文將通過(guò)代碼示例詳細(xì)的給大家介紹了一下這四種方式,需要的朋友可以參考下2024-04-04SpringBoot在容器中創(chuàng)建實(shí)例@Component和@bean有什么區(qū)別
這篇文章主要介紹了SpringBoot在容器中創(chuàng)建實(shí)例@Component和@bean有什么區(qū)別,在Spring Boot中,@Component注解和@Bean注解都可以用于創(chuàng)建bean。它們的主要區(qū)別在于它們的作用范圍和創(chuàng)建方式2023-03-03Spark調(diào)優(yōu)多線程并行處理任務(wù)實(shí)現(xiàn)方式
這篇文章主要介紹了Spark調(diào)優(yōu)多線程并行處理任務(wù)實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08