如何实现停止中断运行中的线程
如何实现停止中断运行中的线程
-
- ①通过一个volatile变量实现
(多线程环境下,变量可能会以副本形式存储到线程的工作空间如cpu缓存中而导致变量在各个线程中不共享。volatitle关键字可以让变量在各个线程中共享,并且禁止重排序)
/**
* @author Guanghao Wei
* @create 2023-04-11 10:29
* 使用volatile修饰一个标识符来决定是否结束线程
*/
public class InterruptDemo {
static volatile boolean isStop = false;
//volatile表示的变量具有可见性
public static void main(String[] args) {
new Thread(() -> {
while (true) {
if
(isStop) {
System.out.println(Thread.currentThread().getName() + "
isStop的值被改为true,t1程序停止");
break;
}
System.out.println("-----------hello volatile");
}
}, "t1").start();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
isStop = true;
}, "t2").start();
}
}
/**
* -----------hello volatile
* -----------hello volatile
* -----------hello volatile
* -----------hello volatile
* -----------hello volatile
* -----------hello volatile
* t1 isStop的值被改为true,t1程序停止
*/
-
- ②通过AutomicBoolean
- (通过原子类)
- /**
* @author Guanghao Wei
* @create 2023-04-11 10:29
* 使用AtomicBoolean
*/
public class InterruptDemo {
static AtomicBoolean atomicBoolean = new
AtomicBoolean(false);
public static void main(String[] args) {
new Thread(() -> {
while (true) {
if
(atomicBoolean.get()) {
System.out.println(Thread.currentThread().getName() + "
atomicBoolean的值被改为true,t1程序停止");
break;
}
System.out.println("-----------hello atomicBoolean");
}
}, "t1").start();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e)
{
e.printStackTrace();
}
new Thread(() -> {
atomicBoolean.set(true);
}, "t2").start();
}
}
/**
* -----------hello atomicBoolean
* -----------hello atomicBoolean
* -----------hello atomicBoolean
* -----------hello atomicBoolean
* -----------hello atomicBoolean
* t1 atomicBoolean的值被改为true,t1程序停止
*/
-
- ③通过Thread类自带的中断API实例方法实现----在需要中断的线程中不断监听中断状态,一旦发生中断,就执行相应的中断处理业务逻辑stop线程。
- /**
* @author Guanghao Wei
* @create 2023-04-11 10:29
* 使用interrupt() 和isInterrupted()组合使用来中断某个线程
*/
public class InterruptDemo {
static AtomicBoolean atomicBoolean = new
AtomicBoolean(false);
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
if
(Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName() + "
isInterrupted()的值被改为true,t1程序停止");
break;
}
System.out.println("-----------hello isInterrupted()");
}
}, "t1");
t1.start();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e)
{
e.printStackTrace();
}
//t2向t1放出协商,将t1中的中断标识位设为true,希望t1停下来
new Thread(() -> t1.interrupt(),
"t2").start();
//当然,也可以t1自行设置
t1.interrupt();
}
}
/**
* -----------hello isInterrupted()
* -----------hello isInterrupted()
* -----------hello isInterrupted()
* -----------hello isInterrupted()
* t1 isInterrupted()的值被改为true,t1程序停止
*/
- 当前线程的中断标识为true,是不是线程就立刻停止?
答案是不立刻停止,具体来说,当对一个线程,调用interrupt时:
-
- 如果线程处于正常活动状态,那么会将该线程的中断标志设置为true,仅此而已,被设置中断标志的线程将继续正常运行,不受影响,所以interrupt()并不能真正的中断线程,需要被调用的线程自己进行配合才行,对于不活动的线程没有任何影响。
- 如果线程处于阻塞状态(例如sleep,wait,join状态等),在别的线程中调用当前线程对象的interrupt方法,那么线程将立即退出被阻塞状态(interrupt状态也将被清除),并抛出一个InterruptedException异常。
对于静态方法Thread.interrupted()和实例方法isInterrupted()区别在于:
- 静态方法interrupted将会清除中断状态(传入的参数ClearInterrupted为true)
- 实例方法isInterrupted则不会(传入的参数ClearInterrupted为false)
- 可以看到内部都是调用isInterrupted()方法,区别只在于参数 是否要 清理Interrupted状态标志

浙公网安备 33010602011771号