一、什么情况下会抛出Interrupted异常
Interrupt这个词很容易让人产生误解。从字面意思来看,好像是说一个线程运行到一半,把它中断了,然后抛出了InterruptedExcept ion异常,其实并不是。
这个时候,在主线程中调用一句t.interrupt(),请问该线程是否会抛出异常? 答案是不会。
假设这个线程阻塞在一个 synchronized 关键字 的地方,正准备拿锁,如下代码所示。
在主线程中调用一句t.interrupt(),请问该线程是否会抛出异常? 答案是不会。
实际上,只有那些声明了会抛出 InterruptedException 的函数才会抛出异常,也就是下面这些常用的函数:
二、轻量级阻塞与重量级阻塞
轻量级阻塞 能够被中断的阻塞称为轻量级阻塞,对应的线程状态是WAITING或 者TIMED_WAITING
重量级阻塞 像 synchronized 这种不能被中断的阻塞称为重量级阻塞,对应的状态是 BLOCKED
初始线程处于NEW状态,调用start()之后开始执行,进入RUNNING或者READY状态。如果没有调用任何的阻塞函数,线程只会在RUNNING和READY之间切换,也就是系统的时间片调度。这两种状态的切换是操作系统完成的,开发者基本没有机会介入,除了可以调用yield() 函数,放弃对CPU的占用。
一旦调用了图中的任何阻塞函数,线程就会进入WAITING或者TIMED_WAITING状态,两者的区别只是前者为无限期阻塞,后者则传入了一 个时间参数,阻塞一个有限的时间
除了常用的阻塞/唤醒函数,还有一对不太常见的阻塞/唤醒函数,LockSupport.park()/unpark()。这对函数非常关键,Concurrent包中Lock的实现即依赖这一对操作原语。
三、Thread.isInterrupted()与Thread.interrupted()的区别
t.interrupted()相当于给线程发送了一个唤醒的信号, 所以如果线程此时恰好处于WAITING或者TIMED_WAITING状态,就会抛出一个InterruptedException,并且线程被唤醒. 而如果线程此时并没有被阻塞,则线程什么都不会做。
这两个函数都是线程用来判断自己是否收到过中断信号的,前者是非静态函数,后者是静态函数。二者的区别在于,前者只是读取中断状态,不修改状态; 后者不仅读取中断状态,还会重置中断标志位。