接下来说一下"interrupted()"和"isInterrupted()"两个方法的相同点和不同点。在这之前看一下源码中两个方法的代码,如下:
1 public static boolean interrupted() { 2 return currentThread().isInterrupted(true); 3 } 4 public boolean isInterrupted() { 5 return isInterrupted(false); 6 } 7 /** 8 * Tests if some Thread has been interrupted. The interrupted state 9 * is reset or not based on the value of ClearInterrupted that is10 * passed.11 */12 private native boolean isInterrupted(boolean ClearInterrupted);
相同点都是判断线程的interrupt status是否被设置,若被设置返回true,否则返回false.区别有两点:一:前者是static方法,调用者是current thread,而后者是普通方法,调用者是this current.二:它们其实都调用了Java中的一个native方法isInterrupted(boolean ClearInterrupted); 不同的是前者传入了参数true,后者传入了false.意义就是:前者将清除线程的interrupt state(®3),调用后者线程的interrupt state不受影响。
二:例子。
接下来看一个例子,这个例子说明了两个问题。1.调用interrupt()方法并不会中断一个正在运行的线程.2.若调用sleep()而使线程处于阻塞状态,这时调用interrupt()方法,会抛出InterruptedException,从而使线程提前结束阻塞状态,退出阻塞代码。如下:
1 package interrupt; 2 3 public class Main { 4 /** 5 * @param args 6 */ 7 public static void main(String[] args) { 8 Main main = new Main(); 9 Thread t = new Thread(main.runnable);10 System.out.println("mainmainmain");11 t.start();12 try {13 Thread.sleep(2000);14 } catch (InterruptedException e) {15 // TODO Auto-generated catch block16 e.printStackTrace();17 }18 t.interrupt();19 }20 21 Runnable runnable = new Runnable() {22 @Override23 public void run() {24 int i = 0;25 try {26 while (i
运行结果:
1 mainmainmain2 03 14 25 java.lang.InterruptedException: sleep interrupted6 at java.lang.Thread.sleep(Native Method)7 at interrupt.Main$1.run(Main.java:27)8 at java.lang.Thread.run(Thread.java:619)
三:分析下例子中的中断机制
1.为什么调用interrupt()并不能中断线程?
1 public void interrupt() { 2 if (this != Thread.currentThread()) 3 checkAccess(); 4 5 synchronized (blockerLock) { 6 Interruptible b = blocker; 7 if (b != null) { 8 interrupt0(); // Just to set the interrupt flag 9 b.interrupt();10 return;11 }12 }13 interrupt0();14 }
如上是Java源码中的代码,由此我们看出问题的答案。线程的blocker字段(也就是interrupt status)默认是null(®1)。调用interrupt()方法时,只是运行了®2,并没有进入if语句,所以没调用真正执行中断的代码b.interrupt().
2.若调用sleep()而使线程处于阻塞状态,这时调用interrupt()方法,会抛出InterruptedException,从而使线程提前结束阻塞状态,退出阻塞代码。为什么?
由上图可看出例子中30行代码铺好的异常其实是interrupt()抛出的,而不是sleep()抛出的。