• 中断锁的意义



    前言

    中断锁在实际业务开发中有着重要意义

    可中断锁使得我们可以在多线程环境中更好地处理中断问题,从而提高程序的健壮性和响应性;减少线程阻塞的可能;


    一、什么是可中断锁?

    在持有锁的过程中,如果线程被中断,它不能响应中断,直到释放锁。这可能导致一些问题,比如如果一个线程因为某些原因被长时间阻塞,其他线程也可能会被阻塞,这可能会导致整个程序的性能下降,甚至可能导致死锁。

    可中断锁解决了这个问题。在持有可中断锁的时候,如果线程接收到中断信号,它会立即释放锁,并抛出InterruptedException异常。这样,其他等待该锁的线程就有机会获取该锁,并继续执行

    二、可中断锁的实际意义

    1.非可中断锁导致一直阻塞等待

    两个线程,A 获取锁但是没有释放,B获取同一把锁,由于A没有释放,B只能一直等待;

    public class InterruptedLock {
    
      public static void main(String[] args) {
    
        Lock lock = new ReentrantLock();
    
        Thread thread1 = new Thread(() -> {
          lock.lock();
          try {
            System.out.println(Thread.currentThread().getName() + "线程1获取到锁");
          } catch (Exception e) {
            throw new RuntimeException(e);
          }
        });
        thread1.start();
    
        Thread thread2 = new Thread(() -> {
          try {
            System.out.println(Thread.currentThread().getName() + "线程2等待获取锁");
            Thread.sleep(500);
            lock.lock();
          } catch (Exception e) {
            System.out.println("线程2 被中断");
          }
        });
        thread2.start();
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    等待锁释放截图

    可以看到程序一直不结束,由于线程1未释放锁,线程2一直等待获取锁

    2.改为可中断获取锁

    public class InterruptedLock {
    
      public static void main(String[] args) {
    
        Lock lock = new ReentrantLock();
    
        Thread thread1 = new Thread(() -> {
          lock.lock();
          try {
            System.out.println(Thread.currentThread().getName() + "线程1获取到锁");
          } catch (Exception e) {
            throw new RuntimeException(e);
          }
        });
        thread1.start();
    
        Thread thread2 = new Thread(() -> {
          try {
            System.out.println(Thread.currentThread().getName() + "线程2等待获取锁");
            Thread.sleep(500);
            lock.lock();
          } catch (Exception e) {
            System.out.println("线程2 被中断");
          }
        });
        thread2.start();
    
        try {
          Thread.sleep(2000);
          if (thread2.isAlive()) {
            System.out.println("线程2执行中断");
            thread2.interrupt();
          }else {
            System.out.println("线程2执行完成");
          }
        } catch (InterruptedException e) {
          throw new RuntimeException(e);
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    可中断获取锁后,当一定时间后,可以判断当前线程是否执行完成,如果未完成可以执行中断,提前退出,防止一直阻塞
    可中断锁提前中断


    总结

    在Java中,使用synchronized关键字或ReentrantLock可以实现互斥锁,但在持有锁的过程中,如果线程被中断,它不能响应中断,直到释放锁。这可能导致一些问题,比如如果一个线程因为某些原因被长时间阻塞,其他线程也可能会被阻塞,这可能会导致整个程序的性能下降,甚至可能导致死锁。

    可中断锁解决了这个问题。在持有可中断锁的时候,如果线程接收到中断信号,它会立即释放锁,并抛出InterruptedException异常。这样,其他等待该锁的线程就有机会获取该锁,并继续执行。

  • 相关阅读:
    linux 内存管理
    基于SpringBoot的“1818小酒馆”商城网站的设计与实现毕业设计源码192004
    构建动态交互式H5导航栏:滑动高亮、吸顶和锚点导航技巧详解
    0学习Java(32)
    第五章 Ambari二次开发之自定义Flink服务概述
    watch跟computed的区别
    使用 Allatori 进行 Jar 包混淆
    一文搞清楚Java中的方法、常量、变量、参数
    mac录屏快捷键 - mac截图截屏快捷键 - 自带录屏软件QuickTime Player如何使用
    谷歌数据中心尝试转向主线内核,发起新的项目Project Icebreaker
  • 原文地址:https://blog.csdn.net/qq_32419139/article/details/133821555