Lock 与 InterruptedException

检测中断状态的方法一般是: 循环检测(猜测native方法wait、unsafe的park等方法也是用循环检测); 

对于一个线程 t, 其他线程只能改变其中断状态,系统(线程调度器)检测其中断状态,若被中断则将其唤醒(在阻塞的IO中不唤醒),然后由t检测自己的中断标志并抛出中断异常;

如果t不检查或检查中断而决定不抛出异常,也就是不搭理其他线程的信号,那么t就会像被正常唤醒一样,不过这会破坏系统的锁机制(同步与互斥),所以线程模型都是有系统和框架实现好的,规定其醒来后首先检测中断标志,若是因为被中断而唤醒,则释放资源(比如已经获得的锁,依框架机制而定)并抛出中断异常。


// ReentrantLock.java

 abstract static class Sync extends AbstractQueuedSynchronizer{
     ...
 }
 static final class NonfairSync extends Sync {
     ...
 }
 static final class FairSync extends Sync {
      ...
 }
    
    
   public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
   } 
   
    public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }



检测中断状态的方法一般是: 循环检测(猜测native方法wait、unsafe的park等方法也是用循环检测)


AbstractQueuedSynchronizer.java:

public final void acquireInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (!tryAcquire(arg))
            doAcquireInterruptibly(arg);
    }


AbstractQueuedSynchronizer.java:

170209_HV7g_255456.png

170209_PS3h_255456.png

170334_YBRu_255456.png

170528_AM5b_255456.png

private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
    }


LockSupport的park 可能使当前线程(称其为T)阻塞。当线程T阻塞时,如果其interrupt被调用,则park方法返回,但是park并不抛出InterruptedException, 即不改变T的中断状态,所以需要重新检查T的状态,正如上面的parkAndCheckInterrupt方法所做的一样。注意Thread.interrupted() 方法会返回并清楚当前的中断状态。

171733_NmT2_255456.png

转载于:https://my.oschina.net/u/255456/blog/374531

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值