Java多线程中的ReentrantLock可中断锁详细解读
ReentrantLock可中断锁
ReentrantLock中的lockInterruptibly()方法使得线程可以在被阻塞时响应中断,比如一个线程t1通过lockInterruptibly()方法获取到一个可重入锁,并执行一个长时间的任务,另一个线程通过interrupt()方法就可以立刻打断t1线程的执行,来获取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(); } }
当执行exeInteruptTest()方法时,可以看到线程t1立刻响应了主线程的interrupt()方法:
当执行exeInteruptSynTest()方法时,可以看到t0线程并没有响应中断,两个线程仍然处于相互等待锁释放的状态。
到此这篇关于Java多线程中的ReentrantLock可中断锁详细解读的文章就介绍到这了,更多相关ReentrantLock可中断锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
springboot整合mybatis将sql打印到日志的实例详解
这篇文章主要介绍了springboot整合mybatis将sql打印到日志的实例详解,需要的朋友可以参考下2017-12-12Springboot通过ObjectMapper配置json序列化详解
SpringBoot默认集成Jackson库,其中ObjectMapper类是核心,用于Java对象与JSON字符串的互转,提供配置序列化特性、注册模块等方法,在SpringBoot中可以全局配置JSON格式,如日期格式化、将Long转为字符串,还可以配置序列化时的各种规则,感兴趣的可以了解一下2024-10-10
最新评论