-
和Thread.sleep一样, BlockingQueue的put和take方法会抛出编译器异常 InterruptedException; __如果一个方法抛出InterruptedException, 说明这个方法是一个阻塞方法
-
Thread提供了interrupt(), interrupted(), isInterrupted()方法
public class Thread implements Runnable { ... public void interrupt() { ... } public boolean isInterrupted() { return isInterrupted(false); } public static boolean interrupted() { return currentThread().isInterrupted(true); } }
interrupt()方法的作用是给调用这个方法的线程设置上中断的标志位;
isInterrupted()方法的作用是查询调用这个方法的线程的中断标志位情况;
interrupted()是一个静态方法,它用于查询当前线程的中断状态,并且清空中断标志位
其实isInterrputed()和interrupted()底层用到的是同一个函数isInterrupted(boolean ClearInterrupted),设置true/false决定了中断标志位是否清除
-
每个线程都有一个bool类型的标志位用来表示线程的中断状态, 当调用interrupt时会设置某个线程的这个标志位
-
中断是一种__协作__机制, 对一个线程调用t1.interrupt()不会让他t1停下来,仅仅是告诉t1应该处理
-
处理InterruptedException的方式
(1) 直接传递异常
不捕获异常直接抛出 或捕获异常做简单清理再次抛出
(2) 恢复中断
当代码是Runnable的一部分时只能捕获InterruptedException, 并通过调用当前线程的interrupt()方法恢复中断状态(否则中断状态会消失), 这样更高层代码将看到引发了一个中断
示例
public class TaskRunnable implements Runnable { BlockingQueue<Task> queue; public void run() { try { processTask(queue.take()); } catch (InterruptedException e) { // restore interrupted status Thread.currentThread().interrupt(); } } void processTask(Task task) { // Handle the task } interface Task { } }
__千万不要只捕获InterruptedException异常而不作任何处理!!!__这样线程被中断的证据已经被丢失(中断标志位清除),更高层的代码无法处理
chapter05_基础构建模块_4_阻塞方法与中断方法
最新推荐文章于 2021-08-04 22:20:59 发布