错误用例
下面用例中,一个正在sleep的线程,在调用interrupt后,wait方法检查到isInterrupted()为true,抛出异常, 而catch到异常后没有处理。一个抛出了InterruptedException的线程的在调用interrupt后状态马上就会被置为非中断状态。如果catch语句没有处理异常,则下一 次循环中isInterrupted()为false,线程会继续执行,程序无法正常退出。
import lombok.extern.slf4j.Slf4j; @Slf4j public class SparkStreamThread implements Runnable { public void stopStream() { this.log.warn("Stop Stream!!"); } @Override public void run() { System.out.println(Thread.currentThread().getName() + "将要运行..."); while (!Thread.currentThread().isInterrupted()) { System.out.println(Thread.currentThread().getName() + "运行中"); try { Thread.sleep(400); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + "从阻塞中退出..."); System.out.println("this.isInterrupted()=" + Thread.currentThread().isInterrupted()); } } System.out.println(Thread.currentThread().getName() + "已经终止!"); } public static void main(String argv[]) throws InterruptedException { Thread ta = new Thread(new SparkStreamThread()); ta.start(); Thread.sleep(2000); System.out.println(ta.getName() + "正在被中断..."); ta.interrupt(); System.out.println("ta.isInterrupted()=" + ta.isInterrupted()); } }
正确用例1,异常捕获后终止线程
import lombok.extern.slf4j.Slf4j; @Slf4j public class SparkStreamThread implements Runnable { public void stopStream() { this.log.warn("Stop Stream!!"); } @Override public void run() { System.out.println(Thread.currentThread().getName() + "将要运行..."); while (!Thread.currentThread().isInterrupted()) { System.out.println(Thread.currentThread().getName() + "运行中"); try { Thread.sleep(400); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + "从阻塞中退出..."); Thread.currentThread().interrupt(); System.out.println("this.isInterrupted()=" + Thread.currentThread().isInterrupted()); } } System.out.println(Thread.currentThread().getName() + "已经终止!"); } public static void main(String argv[]) throws InterruptedException { Thread ta = new Thread(new SparkStreamThread()); ta.start(); Thread.sleep(2000); System.out.println(ta.getName() + "正在被中断..."); ta.interrupt(); System.out.println("ta.isInterrupted()=" + ta.isInterrupted()); } }
正确用例2, 使用变量,double check,二次检查
public class ThreadA extends Thread { private boolean isInterrupted=false; int count=0; public void interrupt(){ isInterrupted = true; super.interrupt(); } public void run(){ System.out.println(getName()+"将要运行..."); while(!isInterrupted){ System.out.println(getName()+"运行中"+count++); try{ Thread.sleep(400); }catch(InterruptedException e){ System.out.println(getName()+"从阻塞中退出..."); System.out.println("this.isInterrupted()="+this.isInterrupted()); } } System.out.println(getName()+"已经终止!"); } }