Skip to content

源码:labs/java/runtime-concurrency/queue-strategy-compare/src/QueueStrategyCompare.java

  • 原始路径:labs/java/runtime-concurrency/queue-strategy-compare/src/QueueStrategyCompare.java
  • 类型:java
java
import java.util.concurrent.*;

/**
 * 实验:对比 ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue 在 ThreadPoolExecutor 中的排队与扩容行为。
 * 
 * 参数统一配置:
 * corePoolSize = 1, maximumPoolSize = 2
 * 提交 5 个并发任务,观察不同队列类型对任务排队、核心/非核心线程创建以及拒绝策略触发的差异。
 */
public class QueueStrategyCompare {

    public static void main(String[] args) throws Exception {
        System.out.println("====== 1. ArrayBlockingQueue (有界有上限 capacity=2) ======");
        demo("ArrayBlockingQueue", new ArrayBlockingQueue<>(2));

        Thread.sleep(1000);

        System.out.println("\n====== 2. LinkedBlockingQueue (容量上限 capacity=2) ======");
        demo("LinkedBlockingQueue", new LinkedBlockingQueue<>(2));

        Thread.sleep(1000);

        System.out.println("\n====== 3. SynchronousQueue (零容量直接手递手传递) ======");
        demo("SynchronousQueue", new SynchronousQueue<>());
    }

    private static void demo(String queueType, BlockingQueue<Runnable> queue) throws Exception {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                1,                            // corePoolSize = 1
                2,                            // maximumPoolSize = 2
                5L, TimeUnit.SECONDS,
                queue,
                r -> new Thread(r, queueType + "-worker"),
                new ThreadPoolExecutor.AbortPolicy()
        );

        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            try {
                pool.execute(() -> {
                    try {
                        Thread.sleep(400); // 模拟耗时任务
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
                System.out.println(String.format("[%s] 提交任务 %d 成功 | 队列排队数: %d | 活跃线程数: %d",
                        queueType, taskId, pool.getQueue().size(), pool.getActiveCount()));
            } catch (RejectedExecutionException e) {
                System.out.println(String.format("[%s] 提交任务 %d 失败 | 队列与线程池已满被拒绝", queueType, taskId));
            }
        }

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

        /* 静态阅读参考输出:
         * ====== 1. ArrayBlockingQueue (有界有上限 capacity=2) ======
         * [ArrayBlockingQueue] 提交任务 1 成功 | 队列排队数: 0 | 活跃线程数: 1  (核心线程 1 启动)
         * [ArrayBlockingQueue] 提交任务 2 成功 | 队列排队数: 1 | 活跃线程数: 1  (入队 1/2)
         * [ArrayBlockingQueue] 提交任务 3 成功 | 队列排队数: 2 | 活跃线程数: 1  (入队 2/2,队列满)
         * [ArrayBlockingQueue] 提交任务 4 成功 | 队列排队数: 2 | 活跃线程数: 2  (触发创建非核心线程 2)
         * [ArrayBlockingQueue] 提交任务 5 失败 | 队列与线程池已满被拒绝            (4 个空间全满,任务 5 被拒绝)
         *
         * ====== 3. SynchronousQueue (零容量直接手递手传递) ======
         * [SynchronousQueue] 提交任务 1 成功 | 队列排队数: 0 | 活跃线程数: 1   (核心线程 1 启动)
         * [SynchronousQueue] 提交任务 2 成功 | 队列排队数: 0 | 活跃线程数: 2   (无法入队,直接创建非核心线程 2)
         * [SynchronousQueue] 提交任务 3 失败 | 队列与线程池已满被拒绝             (2 个线程全繁忙,无队列可入,任务 3 被拒绝)
         * [SynchronousQueue] 提交任务 4 失败 | 队列与线程池已满被拒绝
         * [SynchronousQueue] 提交任务 5 失败 | 队列与线程池已满被拒绝
         */
    }
}