一、interrupt()
interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。
注意:线程中断仅仅是置线程的中断状态位,不会中止线程。须要用户本身去监视线程的状态为并作处理。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。
二、interrupted() 和 isInterrupted()html
首先看一下
API中该方法的实现:
1 |
public static boolean interrupted () { |
2 |
return currentThread().isInterrupted( true ); |
该方法就是直接调用当前线程的
isInterrupted(true)的方法。
而后
再来看一下API中 isInterrupted的实现:
1 |
public boolean isInterrupted () { |
2 |
return isInterrupted( false ); |
该方法却直接调用当前线程的isInterrupted(false)的方法。java
所以这两个方法有两个主要区别:
- interrupted 是做用于当前线程,isInterrupted 是做用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不必定是当前运行的线程。例如咱们能够在A线程中去调用B线程对象的isInterrupted方法。)
- 这两个方法最终都会调用同一个方法-----
isInterrupted( Boolean 参数
),
,只不过参数固定为一个是true,一个是false; 注意: isInterrupted( Boolean 参数
)是isInterrupted(
)的重载方法。
因为第二个区别主要体如今调用的方法的参数上,让咱们来看一看这个参数是什么含义
先来看一看被调用的方法 isInterrupted(boolean arg)
(Thread类中重载的方法)的定义:
1 |
private native boolean isInterrupted( boolean ClearInterrupted); |
原来这是一个本地方法,看不到源码。不过不要紧,经过参数名ClearInterrupted咱们就能知道,这个参数表明是否要清除状态位。
若是这个参数为true,说明返回线程的状态位后,要清掉原来的状态位(恢复成原来状况)。这个参数为false,就是直接返回线程的状态位。程序员
这两个方法很好区分,只有当前线程才能清除本身的中断位(对应interrupted()方法)jvm
因而写了个例子想验证一下:this
- public class Interrupt {
- public static void main(String[] args) throws Exception {
- Thread t = new Thread(new Worker());
- t.start();
-
- Thread.sleep(200);
- t.interrupt();
-
- System.out.println("Main thread stopped.");
- }
-
- public static class Worker implements Runnable {
- public void run() {
- System.out.println("Worker started.");
-
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- System.out.println("Worker IsInterrupted: " +
- Thread.currentThread().isInterrupted());
- }
-
- System.out.println("Worker stopped.");
- }
- }
- }
内容很简答:主线程main启动了一个子线程Worker,而后让worker睡500ms,而main睡200ms,以后main调用worker线程的interrupt方法去中断worker,worker被中断后打印中断的状态。下面是执行结果:spa
- Worker started.
- Main thread stopped.
- Worker IsInterrupted: false
- Worker stopped.
Worker明明已经被中断,而isInterrupted()方法居然返回了false,为何呢?
.net
在stackoverflow上搜索了一圈以后,发现有网友提到:能够查看抛出InterruptedException方法的JavaDoc(或源代码),因而我查看了Thread.sleep方法的文档,doc中是这样描述这个InterruptedException异常的:线程
- InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
结论:interrupt方法是用于中断线程的,调用该方法的线程的状态将被置为"中断"状态。注意:线程中断仅仅是设置线程的中断状态位,不会中止线程。因此当一个线程处于中断状态时,若是再由wait、sleep以及jion三个方法引发的阻塞,那么JVM会将线程的中断标志从新设置为false,并抛出一个InterruptedException异常,而后开发人员能够中断状态位“的本质做用-----就是程序员根据try-catch功能块捕捉jvm抛出的InterruptedException异常来作各类处理,好比如何退出线程。总之interrupt的做用就是须要用户本身去监视线程的状态位并作处理。”code
同时能够作这样的理解:
Thread.currentThread().interrupt(); 这个用于清除中断状态,这样下次调用Thread.interrupted()方法时就会一直返回为true,由于中断标志已经被恢复了。
而调用isInterrupted()只是简单的查询中断状态,不会对状态进行修改。xml
interrupt()是用来设置中断状态的。返回true说明中断状态被设置了而不是被清除了。咱们调用sleep、wait等此类可中断(throw InterruptedException)方法时,一旦方法抛出InterruptedException,当前调用该方法的线程的中断状态就会被jvm自动清除了,就是说咱们调用该线程的isInterrupted 方法时是返回false。若是你想保持中断状态,能够再次调用interrupt方法设置中断状态。这样作的缘由是,java的中断并非真正的中断线程,而只设置标志位(中断位)来通知用户。若是你捕获到中断异常,说明当前线程已经被中断,不须要继续保持中断位。 interrupted是静态方法,返回的是当前线程的中断状态。例如,若是当前线程被中断(没有抛出中断异常,不然中断状态就会被清除),你调用interrupted方法,第一次会返回true。而后,当前线程的中断状态被方法内部清除了。第二次调用时就会返回false。若是你刚开始一直调用isInterrupted,则会一直返回true,除非中间线程的中断状态被其余操做清除了。