• 源码解析-Java线程中断源码理解


    java线程的中断,不同于操作系统层面的中断,不是立刻将线程的行动中止,而是设置一种标识位,然后被其他调用方判断并进行处理

    线程中断相关操作,在Thread类中操作   线程的中断位默认为false

    interrupt();   //设置一个线程的中断位为true

    static interrupted();   //调用isInterrupted(),返回当前线程中断位,并重新设置中断位为true

    isInterrupted();    //返回当前线程中断位,并重新设置中断位为false

    native isTnterrupted(boolean clearInterrupted);    //传入是否需要重置中断位为false;并返回当前线程中断位

    中断一个线程,就是设置该线程的中断位为true,具体怎么处理由客户端自己处理

    中断的具体用途,例如

    来自 Object 类的 wait()、wait(long)、wait(long, int),

    来自 Thread 类的 join()、join(long)、join(long, int)、sleep(long)、sleep(long, int)

    都会抛出throws InterruptedException, 如果线程A调用这些方法后处于阻塞状态,被线程B中断线程A的阻塞状态,会抛出InterruptedException异常 并且设置中断位false

    例如Selector的select方法,轮询过程中一旦被中断方法就会返回。

    如果线程阻塞在 LockSupport.park(Object obj) 方法,也叫挂起,这个时候的中断也会导致线程唤醒,但是唤醒后不会重置中断状态,所以唤醒后去检测中断状态将是 true。

    总之,中断一般应用在一些长时间阻塞的场景——阻塞方法,这种方法一般都会抛出InterruptedException,往往依赖于外部条件来结束阻塞

    中断的处理

    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        // ignore  当外部条件中断了睡眠,抛出InterruptedException异常,被我们捕获后在此处理
    }
    // go on 

    AQS对中断的两种处理方法:

     两种上锁方式lock() 抢锁过程中被中断,不会处理 继续抢锁

    lockInterruptibly()  如果抢锁等待过程中被中断,则抛出异常

    1. lock()里的

     acquire()方法,

    acquireQueued()  在这里

     

    正常执行到这里parkAndCheckInterrupt(),会使线程park()挂起,然后等待阻塞队列的上一个节点释放锁 通过unpark() 将其唤醒

     如果挂起中途被外部中断,则设置中断位interrupted为true,然后循环再次抢锁,抢锁成功返回中断位,抢锁失败就继续挂起.

     2.  lockInterruptiby() 等待过程中如果被中断则抛异常

    上来就判断,如果被中断就直接抛

     

     重点来了, 相比于acquire()方法的等待被中断处理,在这如果等待过程中被中断了就直接抛异常!(之前那个方法是设置个中断位然后继续循环,最后这个中断位能返回获得)

    在并发包中,有非常多的这种处理中断的例子,提供两个方法,分别为响应中断和不响应中断,对于不响应中断的方法,记录中断而不是丢失这个信息。如 Condition 中的两个方法就是这样的:

     通常,如果方法会抛出 InterruptedException 异常,往往方法体的第一句就是

  • 相关阅读:
    吞吐量(TPS)、QPS、并发数、响应时间(RT)
    吞吐量(TPS)、QPS、并发数、响应时间(RT)
    ubuntu 14.04安装pycharm 社区版
    ubuntu 14.04安装pycharm 社区版
    卷积神经网络(4)----目标检测
    卷积神经网络(4)----目标检测
    卷积神经网络(4)----目标检测
    如何搭建自己CDN服务器
    flask
    s16 计算机网络基础
  • 原文地址:https://www.cnblogs.com/ttaall/p/13864424.html
Copyright © 2020-2023  润新知