interrupt、interrupted 、isInterrupted、InterruptedException

来源:互联网 发布:为知笔记转印象笔记 编辑:程序博客网 时间:2024/06/01 18:33

interrupt

interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。
注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态并做处理。一旦线程的中断状态位被置为“中断”,就会抛出interruptedException异常。

interrupted 和 isInterrupted

interruptted实现:
public static boolean interrupted() {        return currentThread().isInterrupted(true);    }

该方法就是直接调用当前线程的isInterrupted(true)方法。
isInterrupted实现:
public boolean isInterrupted() {        return isInterrupted(false);    }
这两个方法有两个主要区别:
  1. interrupted 是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在A线程中去调用B线程对象的isInterrupted方法。)
  2. 这两个方法最终都会调用同一个方法,只不过参数一个是true,一个是false;
第二个区别主要体现在调用的方法的参数上,让我们来看一看这个参数是什么含义
先来看一看被调用的方法 isInterrupted(boolean arg)的定义:
private native boolean isInterrupted(boolean ClearInterrupted);
原来这是一个本地方法,看不到源码。通过参数名我们就能知道,这个参数代表是否要清除状态位。

如果这个参数为true,说明返回线程的状态位后,要清掉原来的状态位。这个参数为false,就是直接返回线程的状态位。

也就是interrupted返回线程的状态位,又清空了状态位。isInterrupted只是返回了线程的状态位。

以下程序看这三个方法的区别:

public class ThreadInterruptTest {public static void main(String[] args) {System.out.println("isInterrupted :"  + Thread.currentThread().isInterrupted());//当前线程没有被中断,返回false;Thread.currentThread().interrupt();//中断了该线程,但是该线程仍会继续执行,该方法只是将线程的状态设置成“中断”状态System.out.println("isInterrupted :" + Thread.currentThread().isInterrupted());//interrupt()执行后,线程被设置成中断状态,返回trueSystem.out.println("interrupted :" + Thread.interrupted());//返回了中断状态:true,又清掉了状态位。System.out.println("isInterrupted :" + Thread.currentThread().isInterrupted());//由于interrupted()清掉了状态位,所以返回false;System.out.println("interrupted :" + Thread.interrupted());//返回false}}

执行结果:


InterruptedException

当一个线程被一些声明了InterruptedException的方法阻塞时,你对这个线程调用Thread.interrupt(),那么大多数这样的方法会立即抛出InterruptedException.如果有些人试着去打断我们的线程,而我们通过捕捉InterruptedException发现了它,这时候最合理的事情就是结束上述被打断的线程(然而大多数时候我们并不处理它)。
public class InterruptedExceptionTest {public static void main(String[] args) throws InterruptedException {ThreadA a = new ThreadA();a.start();Thread.sleep(2000);a.interrupt();System.out.println("a:" + a.isInterrupted());}}class ThreadA extends Thread {@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {System.out.println("正在执行");try {Thread.sleep(1000);} catch (InterruptedException e) {//状态位被清除e.printStackTrace();System.out.println("该线程:" + Thread.currentThread().isInterrupted());//由于状态位被清除,返回falseThread.currentThread().interrupt();}}}}

上面的程序中,主线程调用了a线程的interrupt()方法(线程a的状态位被置为"中断"),线程a捕获了InterruptedException后(此时,线程a的“中断”状态被清除),调用了Thread.currentThread().interrupt(),线程a的状态被置为“中断”,接着继续执行循环条件,线程是中断状态,跳出了循环,线程最终结束了执行。这里,如果在捕获InterruptedException后,不将线程的状态置为“中断”,那么循环仍然会执行,并不会结束。
注意一下几点:
  • 捕获InterruptedException之后应该适当地对它进行处理-大多数情况下适当的处理指的是完全地跳出当前任务/循环/线程。
  • 吞掉InterruptedException不是一个好主意
  • 如果线程在非阻塞调用中被打断了,这时应该使用isInterrupted()。当线程早已被打断(也就是被标记为interrupted)时,一旦进入阻塞方法就应该立刻抛出InterruptedException。



阅读全文
0 0
原创粉丝点击