Java多線程中的ReentrantLock可中斷鎖詳細解讀
ReentrantLock可中斷鎖
ReentrantLock中的lockInterruptibly()方法使得線程可以在被阻塞時響應中斷,比如一個線程t1通過lockInterruptibly()方法獲取到一個可重入鎖,并執(zhí)行一個長時間的任務,另一個線程通過interrupt()方法就可以立刻打斷t1線程的執(zhí)行,來獲取t1持有的那個可重入鎖。而通過ReentrantLock的lock()方法或者Synchronized持有鎖的線程是不會響應其他線程的interrupt()方法的,直到該方法主動釋放鎖之后才會響應interrupt()方法。下面看一個示例:
package com.teriste.thread; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; /** * 測試ReentrantLock可中斷鎖的效果 */ public class ThreadInteruptDemo { ReentrantLock lock1=new ReentrantLock(); ReentrantLock lock2=new ReentrantLock(); /** * ReentrantLock響應中斷 * @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直接響應run方法中的睡眠中斷 Thread.sleep(1000); t1.interrupt(); //阻塞主線程,避免所有線程直接結束,影響死鎖效果 Thread.sleep(10000); } Object syn1=new Object(); Object syn2=new Object(); /** * Synchronized響應中斷 * @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直接響應run方法中的睡眠中斷 Thread.sleep(1000); t1.interrupt(); //阻塞主線程,避免所有線程直接結束,影響死鎖效果 Thread.sleep(100000); } /** * ReentrantLock實現死鎖 */ 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毫秒,保證兩個線程分別已經獲取到兩個鎖,實現相互的鎖等待 TimeUnit.MILLISECONDS.sleep(200); //lock2.lock(); //可中斷的獲取鎖 lock2.lockInterruptibly(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock1.unlock(); lock2.unlock(); System.out.println("線程"+Thread.currentThread().getName()+"正常結束"); } } } /** * Synchronized實現死鎖 */ 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毫秒,再獲取另一個鎖, //保證兩個線程分別已經獲取到兩個鎖,實現相互的鎖等待 TimeUnit.MILLISECONDS.sleep(200); synchronized (lock2){ } } } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println("線程"+Thread.currentThread().getName()+"正常結束"); } } } }
測試代碼:
package com.teriste.thread; import org.junit.Test; public class ThreadInteruptDemoTest { /** * 測試ReentrantLock響應中斷 * @throws Exception */ @Test public void exeInteruptTest() throws Exception{ ThreadInteruptDemo demo=new ThreadInteruptDemo(); demo.exeInterupt(); } /** * 測試Synchronized響應中斷 * @throws Exception */ @Test public void exeInteruptSynTest() throws Exception{ ThreadInteruptDemo demo=new ThreadInteruptDemo(); demo.exeInteruptSyn(); } }
當執(zhí)行exeInteruptTest()方法時,可以看到線程t1立刻響應了主線程的interrupt()方法:
當執(zhí)行exeInteruptSynTest()方法時,可以看到t0線程并沒有響應中斷,兩個線程仍然處于相互等待鎖釋放的狀態(tài)。
到此這篇關于Java多線程中的ReentrantLock可中斷鎖詳細解讀的文章就介紹到這了,更多相關ReentrantLock可中斷鎖內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring中的@EnableScheduling定時任務注解
這篇文章主要介紹了Spring中的@EnableScheduling注解,@EnableScheduling是 Spring Framework 提供的一個注解,用于啟用 Spring 的定時任務功能,通過使用這個注解,可以在 Spring 應用程序中創(chuàng)建定時任務,需要的朋友可以參考下2024-01-01SpringBoot在容器中創(chuàng)建實例@Component和@bean有什么區(qū)別
這篇文章主要介紹了SpringBoot在容器中創(chuàng)建實例@Component和@bean有什么區(qū)別,在Spring Boot中,@Component注解和@Bean注解都可以用于創(chuàng)建bean。它們的主要區(qū)別在于它們的作用范圍和創(chuàng)建方式2023-03-03