Java停止线程的2种方法(附带示例)
在 Java 中,停止一个正在运行的线程需要谨慎处理,因为错误停止线程可能导致程序状态不一致或资源没有被正确释放。
Java 早期版本中提供了 stop() 方法来停止线程,但是这个方法现在已经被废弃了,它并不安全,因为调用 stop() 方法会强制终止线程,可能导致线程资源未被正确释放,从而导致程序出现不可预估的行为,不推荐使用。
下面我们推荐两种正确停止线程的方式。
使用 volatile 标志停止线程的原理比较简单,在线程执行的核心逻辑中,不断地检查标志位,如果标志位被设置为停止,则线程退出执行。
被调用线程的中断状态是通过一个内部的 boolean 型变量来表示的,调用 interrupt() 方法会将这个变量设置为 true。被调用线程可以通过调用 isInterrupted() 方法来检查中断状态,并在适当的时候停止执行。
Java 早期版本中提供了 stop() 方法来停止线程,但是这个方法现在已经被废弃了,它并不安全,因为调用 stop() 方法会强制终止线程,可能导致线程资源未被正确释放,从而导致程序出现不可预估的行为,不推荐使用。
下面我们推荐两种正确停止线程的方式。
volatile标志停止线程
可以定义一个 volatile 的 boolean 型变量来指示线程何时应该停止,线程会定期检查这个变量的值,并在变量状态指示停止时有序地终止。使用 volatile 标志停止线程的原理比较简单,在线程执行的核心逻辑中,不断地检查标志位,如果标志位被设置为停止,则线程退出执行。
public class StoppableRunnable implements Runnable {
private volatile boolean isStopped = false;
public void requestStop() {
isStopped = true;
}
@Override
public void run() {
while (!isStopped) {
// TODO执行任务代码逻辑
// 在适当的位置检查标志
if (Thread.interrupted()) { // 响应中断请求
break;
}
}
// 清理资源和状态
// ...
}
}
// 使用StoppableRunnable类
StoppableRunnable stoppable = new StoppableRunnable();
Thread thread = new Thread(stoppable);
thread.start();
// 当需要停止线程时执行
stoppable.requestStop();
需要注意,在多线程环境下,使用标志位停止线程可能存在并发问题,我们可以使用 synchronized 关键字来同步对标志位的访问,保证线程间的可见性和互斥性。interrupt()方法停止线程
Thread 类提供了 interrupt() 方法来中断线程。使用 interrupt() 方法中断线程的原理是,当一个线程调用另一个线程的 interrupt() 方法时,被调用线程会收到一个中断信号。被调用线程可以通过检查中断状态来决定是否停止执行。被调用线程的中断状态是通过一个内部的 boolean 型变量来表示的,调用 interrupt() 方法会将这个变量设置为 true。被调用线程可以通过调用 isInterrupted() 方法来检查中断状态,并在适当的时候停止执行。
public class InterruptibleRunnable implements Runnable {
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
// TODO执行任务代码逻辑
// 如果任务包含可中断的阻塞方法(如 Thread.sleep()),它将抛出 Inter-ruptedException异常
Thread.sleep(1000);
}
} catch (InterruptedException e) {
// 恢复中断状态以便在后续执行中继续检查
Thread.currentThread().interrupt();
// 清理资源和状态
// ...
}
}
}
// 使用InterruptibleRunnable类
Thread thread = new Thread(new InterruptibleRunnable());
thread.start();
// 当需要停止线程时
thread.interrupt();
interrupt() 方法并不会直接停止线程,它只是设置了线程的中断状态。被调用线程需要自行决定如何对中断信号做出响应。如果线程处于阻塞状态(如调用 sleep()、wait()、join() 等方法),调用 interrupt() 方法会抛出 InterruptedException 异常,可以通过捕获该异常并进行相应处理来停止线程。
ICP备案:
公安联网备案: