0
点赞
收藏
分享

微信扫一扫

关于多线程编程-线程异常重启


测试下面代码,得出结论:

1.线程通过异常导致退出的,将不会被自动重启,当来新任务的时候,不会处理。

2.线程通过在设定时间内未得到使用 (就是空闲线程的存活时间)的线程,当有新任务来的时候,会启动线程来处理。

原因:

  • Java 的线程池(如 ThreadPoolExecutor)并不会对由于异常退出的线程进行自动重启。
  • 异常退出的线程会从线程池中移除,线程池中的线程数量(getPoolSize)会减少。
  • 如果线程池中还有剩余的活跃线程,这些线程会继续处理新任务,但 因异常退出的线程不会自动恢复

import java.util.concurrent.*;

public class ThreadPoolExceptionTest {

    public static void main(String[] args) {
        // 创建一个线程池
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                3, // 核心线程数
                5, // 最大线程数
                60L, TimeUnit.SECONDS, // 空闲线程的存活时间
                new LinkedBlockingQueue<>(), // 任务队列
                Executors.defaultThreadFactory(), // 线程工厂
                new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
        );

        // 定时任务:每隔5秒打印一次线程池状态
        ScheduledExecutorService monitor = Executors.newSingleThreadScheduledExecutor();
        monitor.scheduleAtFixedRate(() -> {
            System.out.println("当前线程池活跃线程数:" + threadPool.getActiveCount());
            System.out.println("当前线程池任务队列长度:" + threadPool.getQueue().size());
            System.out.println("当前线程池已完成任务数:" + threadPool.getCompletedTaskCount());
            System.out.println("当前线程池总任务数:" + threadPool.getTaskCount());
        }, 0, 5, TimeUnit.SECONDS);

        // 提交初始任务
        for (int i = 0; i < 5; i++) {
            threadPool.submit(new RestartableTask(i, threadPool));
        }

        // 关闭线程池
        threadPool.shutdown();
        monitor.shutdown();
    }

    /**
     * 一个任务类,模拟任务执行过程中发生异常。
     */
    static class RestartableTask implements Runnable {
        private final int taskId;
        private final ThreadPoolExecutor threadPool;

        public RestartableTask(int taskId, ThreadPoolExecutor threadPool) {
            this.taskId = taskId;
            this.threadPool = threadPool;
        }

        @Override
        public void run() {
            try {
                System.out.println("线程 " + Thread.currentThread().getName() + " 开始处理任务 " + taskId);
                if (Math.random() < 0.5) { // 模拟任务执行中随机发生异常
                    throw new RuntimeException("模拟异常!");
                }
                // 模拟任务耗时
                Thread.sleep(2000);
                System.out.println("线程 " + Thread.currentThread().getName() + " 完成任务 " + taskId);
            } catch (Exception e) {
                System.err.println("线程 " + Thread.currentThread().getName() + " 任务 " + taskId + " 发生异常:" + e.getMessage());
                // 重启任务
                System.out.println("任务 " + taskId + " 将被重新提交!");
                threadPool.submit(new RestartableTask(taskId, threadPool)); // 使用原线程池重新提交任务
            }
        }
    }
}

举报

相关推荐

0 条评论