如何在JVM终止时调用stopThread()方法?附Java线程代码示例
实现JVM终止时调用线程的stopThread()方法
我有以下线程代码,希望在JVM终止时调用
stopThread()方法,求正确实现方式:
public class Test { public static void main(String[] args) { ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(10); for(int i=0;i<5;i++){ scheduledExecutor.submit(new MyRunnable()) } scheduledExecutor.shotdown() ..... } public class MyRunnable implements Runnable { boolean isRunning = true; public void run() { while(isRunning) { Thread.sleep(5000); } } public void stopThread() { isRunning = false; } }
核心实现要点
- 注册JVM关闭钩子:通过
Runtime.getRuntime().addShutdownHook()添加钩子线程,JVM终止(包括正常退出、收到终止信号)时会自动执行该线程逻辑,在此处调用所有MyRunnable实例的stopThread()。 - 保证变量内存可见性:
isRunning必须用volatile修饰,否则多线程环境下,工作线程可能无法及时感知到变量的修改,导致线程无法停止。 - 保存线程实例引用:需要把所有创建的
MyRunnable实例存入集合,方便关闭钩子遍历调用停止方法。 - 处理中断异常:
Thread.sleep()会响应中断并抛出InterruptedException,捕获后需直接退出循环,确保线程能及时终止。 - 修正线程池关闭逻辑:原代码
shotdown()是拼写错误,应为shutdown();可结合awaitTermination()等待任务完成,超时则强制关闭。
修正后的完整代码
import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) { // 保存所有MyRunnable实例的集合 List<MyRunnable> runnableList = new ArrayList<>(); ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(10); for(int i = 0; i < 5; i++){ MyRunnable runnable = new MyRunnable(); runnableList.add(runnable); scheduledExecutor.submit(runnable); } // 注册JVM关闭钩子 Runtime.getRuntime().addShutdownHook(new Thread(() -> { // 遍历调用所有实例的stopThread() for(MyRunnable runnable : runnableList){ runnable.stopThread(); } // 关闭线程池并等待任务完成 scheduledExecutor.shutdown(); try { if (!scheduledExecutor.awaitTermination(5, TimeUnit.SECONDS)) { // 超时则强制关闭线程池 scheduledExecutor.shutdownNow(); } } catch (InterruptedException e) { scheduledExecutor.shutdownNow(); } })); // 其他业务逻辑... } } class MyRunnable implements Runnable { // volatile修饰保证多线程下的内存可见性 private volatile boolean isRunning = true; @Override public void run() { while(isRunning){ try { Thread.sleep(5000); // 此处添加你的业务逻辑 } catch (InterruptedException e) { // 捕获中断异常后退出循环,确保线程终止 Thread.currentThread().interrupt(); // 保留中断状态 break; } } System.out.println("线程已停止"); } public void stopThread() { isRunning = false; // 主动中断线程,加快停止速度 Thread.currentThread().interrupt(); } }
内容的提问来源于stack exchange,提问作者Srinivasan
相关产品推荐
相关产品推荐

