暴力停止方法 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;
}
@Override
public 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();
}
@Override
public 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;
@Override
public 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;
@Override
public 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();
}
}
输出结果