Java多线程中的ReentrantLock可中断锁详细解读

 更新时间:2023年12月14日 08:54:34   作者:Terisadeng  
这篇文章主要介绍了Java多线程中的ReentrantLock可中断锁详细解读,ReentrantLock中的lockInterruptibly()方法使得线程可以在被阻塞时响应中断,比如一个线程t1通过lockInterruptibly()方法获取到一个可重入锁,并执行一个长时间的任务,需要的朋友可以参考下

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可中断锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java使用Thumbnailator实现图片处理功能

    Java使用Thumbnailator实现图片处理功能

    Thumbnailator是一个简单且功能强大的Java库,用于生成缩略图和执行其他图片处理任务,在这篇博客中,我们将介绍如何使用Thumbnailator进行图片的缩放、裁剪、旋转等操作,需要的朋友可以参考下
    2024-07-07
  • SpringBoot自定义FailureAnalyzer详解

    SpringBoot自定义FailureAnalyzer详解

    这篇文章主要介绍了SpringBoot自定义FailureAnalyzer详解,FailureAnalyzer是一种在启动时拦截 exception 并将其转换为 human-readable 消息的好方法,包含在故障分析中,需要的朋友可以参考下
    2023-11-11
  • Java实现将Markdown转换为纯文本

    Java实现将Markdown转换为纯文本

    这篇文章主要为大家详细介绍了两种在 Java 中实现 Markdown 转纯文本的主流方法,文中的示例代码讲解详细,大家可以根据需求选择适合的方案
    2025-03-03
  • Spring Boot 3.x 开发中分布式 Session 共享的序列化问题小结

    Spring Boot 3.x 开发中分布式 Session 共享的序

    分布式 Session 共享是构建高可用应用的关键技术,而序列化则是其中的核心环节,本文提供的方案和示例,希望能帮助开发者在Spring Boot 3.x 中从容应对分布式Session 序列化的挑战,构建稳健的微服务架构,感兴趣的朋友跟随小编一起看看吧
    2026-03-03
  • java ConcurrentHashMap锁分段技术及原理详解

    java ConcurrentHashMap锁分段技术及原理详解

    这篇文章主要介绍了java ConcurrentHashMap锁分段技术详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Spring Boot实现qq邮箱验证码注册和登录验证功能

    Spring Boot实现qq邮箱验证码注册和登录验证功能

    这篇文章主要给大家介绍了关于Spring Boot实现qq邮箱验证码注册和登录验证功能的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • java对接阿里通义千问的简单教程

    java对接阿里通义千问的简单教程

    有的项目可能需要用到直接外部调用阿里通义千问的接口,下面这篇文章主要介绍了java对接阿里通义千问的简单教程,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-03-03
  • Java中BIO、NIO和AIO的区别、原理与用法

    Java中BIO、NIO和AIO的区别、原理与用法

    这篇文章主要介绍了Java中BIO、NIO和AIO的区别、原理与用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • 如何把spring boot项目部署到tomcat容器中

    如何把spring boot项目部署到tomcat容器中

    本文给大家分享如何把spring boot项目部署到tomcat容器中,本文给大家介绍的非常详细,需要的朋友参考下
    2017-04-04
  • SpringBoot如何实现文件下载

    SpringBoot如何实现文件下载

    这篇文章主要介绍了SpringBoot如何实现文件下载问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11

最新评论