Skip to content

源码:labs/java/runtime-concurrency/thread-pool-basics/src/ThreadPoolBasics.java

  • 原始路径:labs/java/runtime-concurrency/thread-pool-basics/src/ThreadPoolBasics.java
  • 类型:java
java
import java.util.concurrent.*;

/**
 * 实验:线程池 7 大核心参数、生命周期与拒绝策略行为演示
 *
 * 核心验证点:
 * 1. 线程池任务处理逻辑:先用 corePoolSize -> 满则入 queue -> queue 满则扩充至 maximumPoolSize -> 满则触发 RejectedExecutionHandler。
 * 2. CallerRunsPolicy 在主线程/提交线程直接执行任务的影响(Android 中如果在 UI 线程提交会导致卡顿/ANR)。
 */
public class ThreadPoolBasics {

    public static void main(String[] args) throws Exception {
        System.out.println("====== 场景 1:核心参数与扩容流程演示 (AbortPolicy 抛出异常) ======");
        testPoolExpansionAndAbort();

        System.out.println("\n====== 场景 2:拒绝策略演示 (CallerRunsPolicy 由提交线程直接执行) ======");
        testCallerRunsPolicy();
    }

    /**
     * 演示配置:
     * corePoolSize = 2, maximumPoolSize = 4, workQueue 容量 = 2
     * 提交 7 个任务:
     * - 任务 1, 2:直接分配给 2 个核心线程执行 (active = 2)
     * - 任务 3, 4:进入阻塞队列等待 (queue size = 2)
     * - 任务 5, 6:队列满了,创建 2 个非核心线程执行 (active = 4, maximumPoolSize 达到上限)
     * - 任务 7:队列与线程数均满,触发 AbortPolicy 抛出 RejectedExecutionException 异常
     */
    static void testPoolExpansionAndAbort() throws Exception {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                2,                            // corePoolSize
                4,                            // maximumPoolSize
                1L, TimeUnit.SECONDS,        // keepAliveTime
                new ArrayBlockingQueue<>(2),  // capacity = 2
                new ThreadFactory() {
                    private int count = 1;
                    @Override
                    public Thread newThread(Runnable r) {
                        return new Thread(r, "basics-worker-" + count++);
                    }
                },
                new ThreadPoolExecutor.AbortPolicy()
        );

        for (int i = 1; i <= 7; i++) {
            final int taskId = i;
            try {
                pool.execute(() -> {
                    try {
                        Thread.sleep(500); // 模拟耗时任务
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
                System.out.println(String.format("提交任务 %d 成功 | 活跃线程数: %d | 队列任务数: %d",
                        taskId, pool.getActiveCount(), pool.getQueue().size()));
            } catch (RejectedExecutionException e) {
                System.out.println(String.format("提交任务 %d 失败 | 触发 AbortPolicy 拒绝策略(抛出异常)", taskId));
            }
        }

        pool.shutdown();
        pool.awaitTermination(2, TimeUnit.SECONDS);

        /* 静态阅读参考输出:
         * ====== 场景 1:核心参数与扩容流程演示 (AbortPolicy 抛出异常) ======
         * 提交任务 1 成功 | 活跃线程数: 1 | 队列任务数: 0
         * 提交任务 2 成功 | 活跃线程数: 2 | 队列任务数: 0
         * 提交任务 3 成功 | 活跃线程数: 2 | 队列任务数: 1
         * 提交任务 4 成功 | 活跃线程数: 2 | 队列任务数: 2
         * 提交任务 5 成功 | 活跃线程数: 3 | 队列任务数: 2
         * 提交任务 6 成功 | 活跃线程数: 4 | 队列任务数: 2
         * 提交任务 7 失败 | 触发 AbortPolicy 拒绝策略(抛出异常)
         */
    }

    /**
     * 演示 CallerRunsPolicy:
     * 线程池满了之后,被拒绝的任务会直接在【调用 execute 的当前线程(如 main 线程)】同步执行。
     * Android 警告:如果在 UI 主线程中提交任务并触发了 CallerRunsPolicy,该耗时任务会在主线程同步跑,导致界面直接卡死引发 ANR!
     */
    static void testCallerRunsPolicy() throws Exception {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                1, 1,
                1L, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(1),
                r -> new Thread(r, "caller-runs-worker"),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );

        for (int i = 1; i <= 3; i++) {
            final int taskId = i;
            pool.execute(() -> {
                System.out.println(String.format("任务 %d 在线程 [%s] 上开始执行...",
                        taskId, Thread.currentThread().getName()));
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
            System.out.println("提交任务 " + taskId + " 完成");
        }

        pool.shutdown();
        pool.awaitTermination(2, TimeUnit.SECONDS);

        /* 静态阅读参考输出:
         * ====== 场景 2:拒绝策略演示 (CallerRunsPolicy 由提交线程直接执行) ======
         * 任务 1 在线程 [caller-runs-worker] 上开始执行...
         * 提交任务 1 完成
         * 提交任务 2 完成
         * 任务 3 在线程 [main] 上开始执行...  <-- 注意:任务 3 被退回给调用者线程 (main) 同步执行!
         * 提交任务 3 完成
         * 任务 2 在线程 [caller-runs-worker] 上开始执行...
         */
    }
}