最近在看B站小灰灰的多线程篇(想灵活运用多线程的大家也可以去B站学习哟),讲到了中断,中断这个概念给我的感觉一直很模糊,那我们就顺着小灰灰的教学思路一起探讨一下这个玩意儿吧。
我们在使用CompleteFuture时获取执行结果时候有两个方法,一个是get(),一个是join()。get会要求客户端程序员强制捕获异常,我们在调用线程的sleep方法时也会抛出相同的异常,这个异常就是 InterruptedException 中断异常
那么什么是 InterruptedException 异常呢?我们先看看源码注释吧
翻译成中文:
当线程状态处于等待,休眠,或者其他方式被占据,并且线程在活动之前或者期间被中断时抛出。有时某个方法可能希望测试当前线程是否被中断,如果是,则立即抛出异常,下面的代码可以实现这个效果
if (Thread.interrupted()) // 清除中断状态!
抛出新的中断异常();
那么什么时候线程会抛出中断异常呢?
我们来回顾一下线程的几种状态:在Thread类中存在一个名字叫State的内部类
public enum State {
/**
* Thread state for a thread which has not yet started.
* 尚未启动的线程状态。
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
* 可运行线程的线程状态。处于可运行状态的线程正在 Java 虚拟机中执行,但它可能正在等待来
* 自操作系统的其他资源,例如处理器。
*
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
* 线程阻塞等待监视器锁的线程状态。处于阻塞状态的线程正在等待监视器锁进入同步块/方法或调
* 用后重新进入同步块/方法
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*
* 等待线程的线程状态。由于调用以下方法之一,线程处于等待状态:
* Object.wait 没有超时
* Thread.join 没有超时
* LockSupport.park
* 处于等待状态的线程正在等待另一个线程执行特定操作。例如,一个向对象调用
* Object.wait() 的线程正在等待另一个线程对该对象调用 Object.notify() 或
* Object.notifyAll()。已调用 Thread.join() 的线程正在等待指定线程终止。
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
* 有指定等待时间的等待线程的线程状态。
* 线程由于调用其中之一而处于定时等待状态
* 具有指定正等待时间的以下方法:
*
* Object.wait with timeout
* Thread.join with timeout
* LockSupport.parkNanos
* LockSupport.parkUntil
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
* 已终止线程的线程状态。线程已完成执行。
*/
TERMINATED;
}
现在我们来想想下面三个问题:
1.线程在sleep的时候,是什么状态?
2.在哪些情况下会抛出 InterruptedException ?
3.如果线程没有睡眠,调用它的interrupt会怎样?
答案:
1:线程sleep时候如果没有设置超时时间的时候处于WAITING,否则TIME_WAITING状态
2: 通过的注解可知 线程处于WAITING和TIME_WAITING ,BLOCKED 状态或者由这三种状态转为Runable状态的过程中如果被中断则会收到中断异常
3:会改变线程的中断状态,不会抛出异常。
总结:线程是否中断与线程是否处于活跃状态无关,线程中断只是个标志,非活跃状态的线程之所以中断后会抛出异常是因为若不抛出异常,线程回不到活跃状态(不能提前醒来)。