③. 如何使用中断标识停止线程
- ①. 在需要中断的线程中不断监听中断状态,一旦发生中断,就执行型对于的中断处理业务逻辑
- ②. 三种中断标识停止线程的方式
- 通过一个volatile变量实现
- 通过AtomicBoolean
- 通过Thread类自带的中断API方法实现
public class InterruptDemo{ static volatile boolean isStop = false; static AtomicBoolean atomicBoolean = new AtomicBoolean(false); public static void m3(){ Thread t1 = new Thread(() -> { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("-----isInterrupted() = true,程序结束。"); break; } System.out.println("------hello Interrupt"); } }, "t1"); t1.start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { t1.interrupt();//修改t1线程的中断标志位为true },"t2").start(); } /** * 通过AtomicBoolean */ public static void m2(){ new Thread(() -> { while(true) { if(atomicBoolean.get()) { System.out.println("-----atomicBoolean.get() = true,程序结束。"); break; } System.out.println("------hello atomicBoolean"); } },"t1").start(); //暂停几秒钟线程 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { atomicBoolean.set(true); },"t2").start(); } /** * 通过一个volatile变量实现 */ public static void m1(){ new Thread(() -> { while(true) { if(isStop) { System.out.println("-----isStop = true,程序结束。"); break; } System.out.println("------hello isStop"); } },"t1").start(); //暂停几秒钟线程 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { isStop = true; },"t2").start(); } }
③. 当前线程的中断标识为true,是不是就立刻停止?
线程调用interrupt()时
(①. 如果线程处于正常活动状态,那么会将线程的中断标志设置位true,仅此而已。被设置中断标志的线程将继续正常运行,不受影响。所以,interrupt( )并不能真正的中断线程,需要被调用的线程自己进行配合才行②. 如果线程处于被阻塞状态(例如处于sleep、wait、join等状态),在别的线程中调用当前线程对象的interrupt方法,那么线程立即被阻塞状态,并抛出一个InterruptedException异常)
中断只是一种协同机制,修改中断标识位仅此而已,不是立即stop打断
sleep方法抛出InterruptedException后,中断标识也被清空置为false,我们在catch没有通过调用th.interrupt( )方法再次将中断标识位设置位true,这就是导致无限循环了
public static void m5() { Thread t1 = new Thread(() -> { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("-----isInterrupted() = true,程序结束。"); break; } try { Thread.sleep(500); } catch (InterruptedException e) { //线程的中断标志位重新设置为false,无法停下,需要再次掉interrupt()设置true Thread.currentThread().interrupt();//??????? e.printStackTrace(); } System.out.println("------hello Interrupt"); } }, "t1"); t1.start(); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { t1.interrupt();//修改t1线程的中断标志位为true },"t2").start(); } /** *中断为true后,并不是立刻stop程序 */ public static void m4() { //中断为true后,并不是立刻stop程序 Thread t1 = new Thread(() -> { for (int i = 1; i <= 300; i++) { System.out.println("------i: " + i); } System.out.println("t1.interrupt()调用之后02: "+Thread.currentThread().isInterrupted()); }, "t1"); t1.start(); System.out.println("t1.interrupt()调用之前,t1线程的中断标识默认值: "+t1.isInterrupted()); try { TimeUnit.MILLISECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } //实例方法interrupt()仅仅是设置线程的中断状态位设置为true,不会停止线程 t1.interrupt(); //活动状态,t1线程还在执行中 System.out.println("t1.interrupt()调用之后01: "+t1.isInterrupted()); try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } //非活动状态,t1线程不在执行中,已经结束执行了。 System.out.println("t1.interrupt()调用之后03: "+t1.isInterrupted()); }