Java ThreadPool

Java ThreadPool

线程池 ThreadPoolExecutor

public class ThreadPoolExample {

    public static void main(String[] args) {
        // 创建自定义线程工厂
        ThreadFactory customeThreadFactory = new ThreadFactory() {
            private final AtomicInteger count = new AtomicInteger(1);

            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("自定义线程-" + count.getAndIncrement());
                return thread;
            }
        };

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,  // 核心线程数
                2,              // 最大线程数
                60L,            // 临时线程空闲存活时间
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(2),// 队列容量
                customeThreadFactory,
                new ThreadPoolExecutor.CallerRunsPolicy()// 触发拒绝策略(CallerRunsPolicy)
        );

        // 提交任务
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println(Thread.currentThread().getName() + " 执行任务 " + taskId);
                return taskId;
            });
        }

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

处理流程:

  • 第1个任务:
    创建核心线程处理(1个核心线程)
  • 第2、3个任务:
    进入队列等待(队列容量2个)
  • 第4个任务:
    创建临时线程处理(最大线程数2 - 核心线程数1 = 1个临时线程)
  • 第5个任务:
    触发拒绝策略(CallerRunsPolicy)
    在调用者线程中执行

临时线程:
keepAliveTime = 60L // 临时线程空闲存活时间

  • 临时线程在空闲超过60秒后会被回收。
  • 核心线程默认不回收。
  • 可以通过 allowCoreThreadTimeOut(true) 允许回收核心线程。

如何设置合适的参数:
如何设置合适的参数

  • 核心线程数设置考虑因素:
    • CPU密集型:通常设置为CPU核心数+1
    • IO密集型:可以设置为CPU核心数*2
    • 混合型:CPU核心数(1+平均等待时间/平均工作时间)
  • 最大线程数设置考虑因素:
    • 系统内存大小
    • 任务的响应时间要求
    • 任务的类型(CPU密集或IO密集)
    • 示例配置
// CPU密集型配置
int cpuCores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor cpuIntensiveExecutor = new ThreadPoolExecutor(
    cpuCores + 1,                  // 核心线程数
    cpuCores + 1,                  // 最大线程数
    60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(1000)
);

// IO密集型配置
ThreadPoolExecutor ioIntensiveExecutor = new ThreadPoolExecutor(
    cpuCores * 2,                  // 核心线程数
    cpuCores * 4,                  // 最大线程数
    60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(2000)
);

核心线程用于处理正常负载。
临时线程用于处理突发负载。
参数设置需要根据实际业务场景调整和测试。

CallerRunsPolicy 的作用:

  • 流量控制
    • 当线程池满载时,让调用者自己执行任务。
    • 这会降低任务提交的速度。
    • 起到自然的背压作用。
  • 防止任务丢失
    • 不像 DiscardPolicy 直接丢弃任务。
    • 不像 AbortPolicy 抛出异常。
    • 确保任务最终会被执行。
  • 优缺点
    • 优点:不会丢失任务。
    • 缺点:可能会影响调用者线程的响应时间。

评论

暂无

添加新评论