暴力停止方法 stop
该方法是不安全的,已经过时的方法,在其方法描述上 This method is inherently unsafe,这个方法实际上是不安全的
package com.alibaba.fescar.core.protocol.test;public class TestThreadStop {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{for (int i = 0; i < 10000; i++) {System.out.println(i);}});thread.start();// 保证子线程thread进入运行状态Thread.sleep(10);thread.stop();}
}
输出结果
发现线程运行打印到255的时候,线程终止执行
周期性检查条件变量
指定一个线程可见的变量,循环检查此变量的状态,停止线程,使用volatile关键字保证可见性(内存屏障)
package com.alibaba.fescar.core.protocol.test;public class TestThreadStop {static class MyThread extends Thread {//条件变量private volatile boolean stop = false;private int i = 0;public void end() {stop = true;}@Overridepublic void run() {//循环检查条件变量while (!stop) {i++;System.out.println(i);}}}public static void main(String[] args) throws InterruptedException {MyThread thread = new MyThread();thread.start();// 保证子线程thread进入运行状态Thread.sleep(10);thread.end();}
}
输出结果
条件变量结合中断
interrupt方法用来设置线程的中断状态,如果目标线程正阻塞于wait、sleep等方法时,首先会清除目前线程的中断状态,然后抛出java.lang.InterruptedException异常
package com.alibaba.fescar.core.protocol.test;public class TestThreadStop {static class MyThread extends Thread {//条件变量private volatile boolean stop = false;private int i = 0;public void end() {stop = true;this.interrupt();}@Overridepublic void run() {//循环检查条件变量while (!stop) {//业务代码i++;System.out.println(i);try {Thread.sleep(100);} catch (InterruptedException e) {System.out.println("线程被中断");e.printStackTrace();}}}}public static void main(String[] args) throws InterruptedException {MyThread thread = new MyThread();thread.start();// 保证子线程thread进入运行状态Thread.sleep(10);thread.end();}
}
输出结果
使用Thread.isInterrupted()来代替条件变量
使用Thread.isInterrupted()替代条件变量,但还是上边强调的问题,如果线程在sleep和wait阶段被打断,会清除打断状态,抛出异常,还会继续运行
package com.alibaba.fescar.core.protocol.test;public class TestThreadStop {static class MyThread extends Thread {private int i = 0;@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {i++;System.out.println(i);try {Thread.sleep(100);} catch (InterruptedException e) {System.out.println("线程被中断");e.printStackTrace();}}}}public static void main(String[] args) throws InterruptedException {MyThread thread = new MyThread();thread.start();// 保证子线程thread进入运行状态Thread.sleep(1000);thread.interrupt();}
}
输出结果
如何解决打断继续运行的问题,只需要在处理异常时再次打断即可,如果子线程不sleep呢,情况是不需要再次打断的
package com.alibaba.fescar.core.protocol.test;public class TestThreadStop {static class MyThread extends Thread {private int i = 0;@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {i++;System.out.println(i);try {Thread.sleep(100);} catch (InterruptedException e) {System.out.println("线程被中断");e.printStackTrace();// 再次打断this.interrupt();}}}}public static void main(String[] args) throws InterruptedException {MyThread thread = new MyThread();thread.start();// 保证子线程thread进入运行状态Thread.sleep(1000);thread.interrupt();}
}
输出结果