结束线程方法2 Java提供的中断机制
package com.mozq.thread.interrupt; /** * 注意:调用interrupt()方法,并不会结束线程。 * 结束线程的语义:需要我们自己使用3个中断方法构建。 * * 没有任何语言方面的需求一个被中断的线程应该终止。 * 中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断。 * 某些线程非常重要,以至于它们应该不理会中断,而是在处理完抛出的异常之后继续执行。 * 但是更普遍的情况是,一个线程将把中断看作一个终止请求,这种线程的run方法遵循如下形式 public void run() { try { ... * 不管循环里是否调用过线程阻塞的方法如sleep、join、wait,这里还是需要加上 * !Thread.currentThread().isInterrupted()条件,虽然抛出异常后退出了循环,显 * 得用阻塞的情况下是多余的,但如果调用了阻塞方法但没有阻塞时,这样会更安全、更及时。 while (!Thread.currentThread().isInterrupted()&& more work to do) { do more work } } catch (InterruptedException e) { //线程在wait或sleep期间被中断了 } finally { //线程结束前做一些清理工作 } } 上面是while循环在try块里,如果try在while循环里时,因该在catch块里重新设置一下中断标示, 因为抛出InterruptedException异常后,中断标示位会自动清除,此时应该这样: public void run() { while (!Thread.currentThread().isInterrupted()&& more work to do) { try { ... sleep(delay); } catch (InterruptedException e) { Thread.currentThread().interrupt();//重新设置中断标示 } } } * 结束线程方法2:interrupt()方法,interrupted()方法和isInterrupted()方法 * 该方法的中断语义详细定义在说明文档中。和通常所说的中断意思不一致。 * interrupt()方法用于设置: * 如果线程处于wait,sleep,join阻塞,则会发生中断异常。中断状态为被清除。 * 一般情况则导致中断状态位被设置 * isInterrupted()检测不清除 * interrupted()检测并清除。 * 通过这3个方法,适用于一个线程向另一个线程发送信息,并被B线程处理。 * 可以用来实现线程A根据情况结束线程B的语义。 * * 分成2种情况,1.线程处于阻塞状态2.线程处于正常运行 * 线程处于正常运行 * public class ThreadSafe extends Thread { public void run() { while (!isInterrupted()){ //do something, but no throw InterruptedException } } } 线程处于阻塞状态 public class ThreadSafe extends Thread { public void run() { while (!isInterrupted()){ //非阻塞过程中通过判断中断标志来退出 try{ Thread.sleep(5*1000);//阻塞过程捕获中断异常来退出 }catch(InterruptedException e){ e.printStackTrace(); break;//捕获到异常之后,执行break跳出循环。 } } } } 1 * @author jie * */ public class MyInterruptMethod { public static void main(String[] args) { Thread t = new Thread() { //方法1: /* @Override public void run() { try { while(!Thread.currentThread().isInterrupted()) { System.out.println(Thread.currentThread().getName() + "...run"); Thread.sleep(100); } } catch (InterruptedException e) {} } */ @Override public void run() { while(!Thread.currentThread().isInterrupted()) { System.out.println(Thread.currentThread().getName() + "...run"); try { Thread.sleep(10); } catch (InterruptedException e) { //因为虚拟机处理interrupt调用时,如果方法处于阻塞,会抛出异常并清除中断标志,所以此处需要重置。 Thread.currentThread().interrupt(); //return; //break; } } } }; t.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //业务逻辑。。。 //此处想结束线程 t.interrupt(); } }