Java线程池参数案例

wen java案例 4

本文目录导读:

Java线程池参数案例

  1. 核心参数说明
  2. 参数配置案例
  3. 参数选择建议
  4. 最佳实践总结
  5. 关键注意事项

我为您详细介绍Java线程池的核心参数,并通过具体案例说明如何配置。

核心参数说明

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    corePoolSize,      // 核心线程数
    maximumPoolSize,   // 最大线程数
    keepAliveTime,     // 空闲线程存活时间
    TimeUnit.SECONDS,  // 时间单位
    workQueue,         // 任务队列
    threadFactory,     // 线程工厂
    handler            // 拒绝策略
);

参数配置案例

案例1:CPU密集型任务

public class CPUIntensiveExample {
    public static void main(String[] args) {
        // 获取CPU核心数
        int cpuCores = Runtime.getRuntime().availableProcessors();
        // CPU密集型任务:核心线程数 = CPU核心数 + 1
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            cpuCores,                    // 核心线程数
            cpuCores + 1,               // 最大线程数
            60L,                         // 空闲线程存活时间
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(100),  // 有界队列
            new ThreadFactory() {
                private AtomicInteger count = new AtomicInteger();
                @Override
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r);
                    thread.setName("CPU-Thread-" + count.incrementAndGet());
                    thread.setDaemon(false);
                    return thread;
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy()  // 调用者执行策略
        );
        // 提交CPU密集型任务
        for (int i = 0; i < 100; i++) {
            final int taskId = i;
            executor.execute(() -> {
                // 模拟CPU密集型计算
                long sum = 0;
                for (int j = 0; j < 1000000; j++) {
                    sum += j;
                }
                System.out.println("Task " + taskId + " completed, sum=" + sum);
            });
        }
        executor.shutdown();
    }
}

案例2:IO密集型任务

public class IOIntensiveExample {
    public static void main(String[] args) {
        // IO密集型任务:核心线程数 = CPU核心数 * 2
        int cpuCores = Runtime.getRuntime().availableProcessors();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            cpuCores * 2,               // 核心线程数
            cpuCores * 4,               // 最大线程数
            30L,                         // 空闲线程存活时间
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(500),  // 有界链表队列
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy()  // 拒绝策略:抛出异常
        );
        // 提交IO密集型任务(模拟网络请求)
        for (int i = 0; i < 200; i++) {
            final int taskId = i;
            executor.execute(() -> {
                try {
                    // 模拟网络IO操作
                    Thread.sleep(1000);
                    System.out.println("IO Task " + taskId + " completed");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        executor.shutdown();
    }
}

案例3:混合型任务(有界队列+自定义拒绝策略)

public class MixedTaskExample {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            5,                          // 核心线程数
            10,                         // 最大线程数
            60L,                         // 空闲线程存活时间
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(50),   // 有界队列,容量50
            new NamedThreadFactory("Mixed"),
            new CustomRejectedExecutionHandler()  // 自定义拒绝策略
        );
        // 提交大量任务测试拒绝策略
        for (int i = 0; i < 100; i++) {
            final int taskId = i;
            try {
                executor.execute(() -> {
                    System.out.println("Processing task: " + taskId + 
                                     " by " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            } catch (RejectedExecutionException e) {
                System.err.println("Task " + taskId + " rejected");
            }
        }
        executor.shutdown();
    }
    // 自定义线程工厂
    static class NamedThreadFactory implements ThreadFactory {
        private final String prefix;
        private final AtomicInteger count = new AtomicInteger();
        public NamedThreadFactory(String prefix) {
            this.prefix = prefix;
        }
        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName(prefix + "-" + count.incrementAndGet());
            return thread;
        }
    }
    // 自定义拒绝策略
    static class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            System.err.println("Task rejected. Active: " + executor.getActiveCount() + 
                             ", Queue size: " + executor.getQueue().size());
            // 记录日志或降级处理
            // 可以在这里实现降级策略
        }
    }
}

案例4:动态配置线程池

public class DynamicThreadPoolConfigurator {
    private volatile ThreadPoolExecutor executor;
    private final int[] queueCapacity = {100, 200, 500, 1000};
    public void reconfigure(int targetLoad) {
        // 根据负载动态调整参数
        int cpuCores = Runtime.getRuntime().availableProcessors();
        // 根据负载调整核心线程数
        int coreThreads;
        if (targetLoad > 80) {  // 高负载
            coreThreads = cpuCores * 2;
        } else if (targetLoad > 50) {  // 中等负载
            coreThreads = cpuCores + 1;
        } else {  // 低负载
            coreThreads = cpuCores / 2;
        }
        executor.setCorePoolSize(coreThreads);
        executor.setMaximumPoolSize(coreThreads * 2);
        // 动态调整队列容量(如果使用ArrayBlockingQueue)
        // 注意:实际项目中可能需要重新创建线程池来调整队列大小
        System.out.println("Thread pool reconfigured: core=" + coreThreads + 
                         ", max=" + coreThreads * 2);
    }
    // 监控线程池状态
    public void monitorPool() {
        System.out.println("=== Thread Pool Status ===");
        System.out.println("Active: " + executor.getActiveCount());
        System.out.println("Core Pool Size: " + executor.getCorePoolSize());
        System.out.println("Maximum Pool Size: " + executor.getMaximumPoolSize());
        System.out.println("Queue Size: " + executor.getQueue().size());
        System.out.println("Completed Tasks: " + executor.getCompletedTaskCount());
    }
}

参数选择建议

核心线程数(corePoolSize)

  • CPU密集型CPU核心数 + 1
  • IO密集型CPU核心数 * 2 或更多
  • 混合型:根据CPU密集和IO密集的比例计算

最大线程数(maximumPoolSize)

  • 通常是核心线程数的 1.5 ~ 3 倍
  • 需要考虑系统资源限制

队列选择

// 有界队列 - 防止内存溢出
new ArrayBlockingQueue<>(100)
// 无界队列 - 可能导致内存溢出
new LinkedBlockingQueue<>()
// 同步队列 - 不缓存任务
new SynchronousQueue<>()

拒绝策略选择

策略 说明 适用场景
AbortPolicy 抛出异常 默认策略,适合重要任务
CallerRunsPolicy 调用者执行 适合降低吞吐量
DiscardPolicy 丢弃任务 适合不重要任务
DiscardOldestPolicy 丢弃最旧任务 适合实时性要求高的场景

最佳实践总结

public class ThreadPoolFactory {
    public static ThreadPoolExecutor createPool(String type) {
        int cpuCores = Runtime.getRuntime().availableProcessors();
        switch (type) {
            case "CPU":
                return new ThreadPoolExecutor(
                    cpuCores, cpuCores + 1, 60L, TimeUnit.SECONDS,
                    new ArrayBlockingQueue<>(100),
                    new ThreadPoolExecutor.CallerRunsPolicy()
                );
            case "IO":
                return new ThreadPoolExecutor(
                    cpuCores * 2, cpuCores * 4, 30L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(500),
                    new ThreadPoolExecutor.AbortPolicy()
                );
            default:
                return new ThreadPoolExecutor(
                    cpuCores, cpuCores * 2, 60L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(200),
                    new ThreadPoolExecutor.CallerRunsPolicy()
                );
        }
    }
}

关键注意事项

  1. 谨慎使用 Executors 工厂方法:很多预定义方法使用无界队列,可能导致OOM
  2. 合理设置队列大小:根据任务量和响应时间要求权衡
  3. 监控线程池状态:定期监控ActiveCount、QueueSize等指标
  4. 优雅关闭:使用 shutdown() 而非 shutdownNow(),给任务完成时间
  5. 参数调整:通过 setCorePoolSize()setMaximumPoolSize() 动态调整

选择参数时需要综合考虑业务场景、系统资源、任务特性等因素,建议先做压力测试,再根据实际表现进行调整。

抱歉,评论功能暂时关闭!