环境
win10,idea
方法
在 Java 中,直接终止一个线程(使用 Thread.stop()
方法)被认为是不安全的操作,并且从 Java 1.2 开始这个方法就被标记为废弃了。这是因为直接停止线程可能会导致资源没有正确释放、对象状态不一致等问题。因此,推荐的做法是通过协作的方式来优雅地终止线程。
以下是一些常见的做法来终止正在运行的线程:
使用标志位
最常见的方式是在你的线程中设置一个标志位,然后定期检查这个标志位,如果标志位被设置为终止信号,则线程可以自行退出循环或结束其工作。
javapublic class MyRunnable implements Runnable {
private volatile boolean running = true;
@Override
public void run() {
while (running) {
// 执行任务
try {
Thread.sleep(100); // 模拟耗时操作
} catch (InterruptedException e) {
// 如果线程被中断,重新设置中断状态并退出
Thread.currentThread().interrupt();
break;
}
}
// 清理资源
cleanup();
}
public void shutdown() {
running = false;
}
private void cleanup() {
// 执行必要的清理工作
}
}
// 在其他地方启动和停止线程
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
// 停止线程
myRunnable.shutdown();
使用 interrupt()
interrupt()
方法用于中断一个线程。它不会立即终止线程,而是设置线程的中断状态。线程应该定期检查这个状态,并在适当的时候退出。
public class MyRunnable implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// 执行任务
try {
Thread.sleep(100); // 模拟耗时操作
} catch (InterruptedException e) {
// 如果线程被中断,重新设置中断状态并退出
Thread.currentThread().interrupt();
break;
}
}
// 清理资源
cleanup();
}
private void cleanup() {
// 执行必要的清理工作
}
}
// 在其他地方启动和停止线程
Thread thread = new Thread(new MyRunnable());
thread.start();
// 停止线程
thread.interrupt();
使用 ExecutorService
如果你使用的是 ExecutorService
来管理线程池,那么可以调用 shutdown()
或 shutdownNow()
方法来关闭线程池中的所有线程。
shutdown()
:平滑地关闭服务,不再接受新的任务,但会等待已提交的任务完成。shutdownNow()
:尝试停止所有正在执行的任务,并阻止新任务的开始。
ExecutorService executor = Executors.newFixedThreadPool(5);
// 提交任务
executor.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 执行任务
try {
Thread.sleep(100); // 模拟耗时操作
} catch (InterruptedException e) {
// 如果线程被中断,重新设置中断状态并退出
Thread.currentThread().interrupt();
break;
}
}
// 清理资源
});
// 关闭线程池
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
}