Java中interrupt()方法详解附带demo

  Thread.interrupt()的做用是通知线程应该中断了,到底中断仍是继续运行,应该由被通知的线程本身处理。当对一个线程,调用 interrupt() 时,java

  1.若是线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程将当即退出被阻塞状态,并抛出一个InterruptedException异常。仅此而已。ide

  2.若是线程处于正常活动状态,那么会将该线程的中断标志设置为 true,仅此而已。被设置中断标志的线程将继续正常运行,不受影响。测试

  首先说第二条,线程正常执行,经过interrupt()方法将其中断标志设置为true,在线程中使用Thread.interrupted()方法判断当前线程是否被设置中断标志。this

public class StopThread implements Runnable { public static void main(String[] args) { StopThread stopThread = new StopThread(); Thread thread = new Thread(stopThread); thread.start(); System.out.println("thread starting..."); try { Thread.sleep(3000); thread.interrupt(); System.out.println("interrupt thread!"); Thread.sleep(3000); thread.join(); System.out.println("main stop!"); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { int i = 1; while (!Thread.interrupted()) i++; System.out.println("i=" + i); System.out.println("thread stop!"); } } 

  输出:spa

thread starting... interrupt thread! i=-937646695 thread stop! main stop!

  这里再说一下interrupted(),贴一下jdk1.8源码的方法注释,当调用这个方法会将中断标志重置,若是线程继续执行,下一次调用这个方法返回为false,除非再次调用interrupt()方法设置一次。简单来讲就是一次interrupt()只对应一次interrupted()的true状态。线程

Tests whether the current thread has been interrupted. The <i>interrupted status</i> of the thread is cleared by this method. In other words, if this method were to be called twice in succession, the second call would return false 

  接下来研究下第一条,再写一个简单的demo,能够看到线程正在sleep中,调用了interrupt()方法后,直接进入catch (InterruptedException e) {}中,而后继续执行线程后续操做。因此在catch中写中止线程的语句,便可达到目的。code

public class StopThread implements Runnable { public static void main(String[] args) { StopThread stopThread = new StopThread(); Thread thread = new Thread(stopThread); thread.start(); System.out.println("thread starting..."); try { Thread.sleep(1000); thread.interrupt(); System.out.println("interrupt thread!"); Thread.sleep(3000); thread.join(); System.out.println("main stop!"); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { System.out.println("throw InterruptedException!"); e.printStackTrace(); } System.out.println("thread stop!"); } }

  输出blog

thread starting... interrupt thread!
throw InterruptedException! thread stop! java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at program.javaTest.threadtest.StopThread.run(StopThread.java:30) at java.lang.Thread.run(Thread.java:745) main stop!

  那么还有个状况,就是调用interrupt()时线程没有处于阻塞,而后线程开始了sleep等三种方法阻塞,这时线程一样会跳入catch (InterruptedException e) {}中,由于中断标志此时为true。源码

public class StopThread implements Runnable { public static void main(String[] args) { StopThread stopThread = new StopThread(); Thread thread = new Thread(stopThread); thread.start(); System.out.println("thread starting..."); try { thread.interrupt(); System.out.println("isInterrupted : " + thread.isInterrupted()); Thread.sleep(3000); thread.join(); System.out.println("main stop!"); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { long l = System.currentTimeMillis(); while (System.currentTimeMillis() - l < 5000); try { Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("entry catch block!"); e.printStackTrace(); } System.out.println("thread stop!"); } }

  输出it

thread starting... isInterrupted : true
entry catch block!
java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at program.javaTest.threadtest.StopThread.run(StopThread.java:30) at java.lang.Thread.run(Thread.java:745) thread stop! main stop!

  这个demo中多了一个thread.isInterrupted()方法,它也是用来测试线程中断表示,不一样的是,它是实例方法,因此返回的是实例thread的中断标志,这样用来在线程外部管理线程的地方获得线程中断状态;另外isInterrupted()方法不会重置中断标志。用这个方法时有另一个发现,当线程进入catch后,中断标志重置为false!!!

P.S.interrupt()方法就讲这么多,它和信号变量一块儿使用能够达到很好的中断线程目的。可是又有了新的问题,如今可以处理sleep等3个阻塞方法,若是线程阻塞在其余方法上,好比IO中的read,该如何处理。这个以后会放在另一篇博文中详细介绍。

相关文章
相关标签/搜索