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 异常,可以通过捕获该异常并进行相应处理来停止线程。