java---interrupt、interrupted和isInterrupted的区别

一、interrupt() 
interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。
注意:线程中断仅仅是置线程的中断状态位,不会中止线程。须要用户本身去监视线程的状态为并作处理。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。

 

二、interrupted() 和 isInterrupted()html

首先看一下 API中该方法的实现:
1 public static boolean interrupted () {
2      return currentThread().isInterrupted(true);
3 }
该方法就是直接调用当前线程的 isInterrupted(true)的方法。
而后 再来看一下API中 isInterrupted的实现:
1 public boolean isInterrupted () {
2      return isInterrupted( false);
3 }

该方法却直接调用当前线程的isInterrupted(false)的方法。java

所以这两个方法有两个主要区别:
  1. interrupted 是做用于当前线程,isInterrupted 是做用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不必定是当前运行的线程。例如咱们能够在A线程中去调用B线程对象的isInterrupted方法。)
  2. 这两个方法最终都会调用同一个方法-----isInterrupted( Boolean 参数),,只不过参数固定为一个是true,一个是false;               注意: isInterrupted( Boolean 参数)是isInterrupted( )的重载方法。
 
因为第二个区别主要体如今调用的方法的参数上,让咱们来看一看这个参数是什么含义
 
先来看一看被调用的方法 isInterrupted(boolean arg) (Thread类中重载的方法)的定义:
1 private native boolean isInterrupted( boolean ClearInterrupted);
原来这是一个本地方法,看不到源码。不过不要紧,经过参数名ClearInterrupted咱们就能知道,这个参数表明是否要清除状态位。

若是这个参数为true,说明返回线程的状态位后,要清掉原来的状态位(恢复成原来状况)。这个参数为false,就是直接返回线程的状态位。程序员

这两个方法很好区分,只有当前线程才能清除本身的中断位(对应interrupted()方法)jvm

 

因而写了个例子想验证一下:this

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到个人代码片
  1. public class Interrupt {  
  2.     public static void main(String[] args) throws Exception {  
  3.         Thread t = new Thread(new Worker());  
  4.         t.start();  
  5.           
  6.         Thread.sleep(200);  
  7.         t.interrupt();  
  8.           
  9.         System.out.println("Main thread stopped.");  
  10.     }  
  11.       
  12.     public static class Worker implements Runnable {  
  13.         public void run() {  
  14.             System.out.println("Worker started.");  
  15.               
  16.             try {  
  17.                 Thread.sleep(500);  
  18.             } catch (InterruptedException e) {  
  19.                 System.out.println("Worker IsInterrupted: " +   
  20.                         Thread.currentThread().isInterrupted());  
  21.             }  
  22.               
  23.             System.out.println("Worker stopped.");  
  24.         }  
  25.     }  
  26. }  

内容很简答:主线程main启动了一个子线程Worker,而后让worker睡500ms,而main睡200ms,以后main调用worker线程的interrupt方法去中断worker,worker被中断后打印中断的状态。下面是执行结果:spa

 

 

[vb]  view plain  copy
 
 在CODE上查看代码片派生到个人代码片
  1. Worker started.  
  2. Main thread stopped.  
  3. Worker IsInterrupted: false  
  4. Worker stopped.  

Worker明明已经被中断,而isInterrupted()方法居然返回了false,为何呢?

.net

在stackoverflow上搜索了一圈以后,发现有网友提到:能够查看抛出InterruptedException方法的JavaDoc(或源代码),因而我查看了Thread.sleep方法的文档,doc中是这样描述这个InterruptedException异常的:线程

 

[html]  view plain  copy
 
 在CODE上查看代码片派生到个人代码片
  1. InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.  



 

[html]  view plain  copy
 
 在CODE上查看代码片派生到个人代码片

结论: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,除非中间线程的中断状态被其余操做清除了。
相关文章
相关标签/搜索