线程池

1 问题

像性能池对吧?一般一个性能池的一个正常工作原理是什么样的?
它里面有哪些核心的参数呢?这些参数是怎么配合做工作的呢?

2 第一种回答

任务提交 → 核心线程执行 → 任务队列缓存 → 非核心线程执行 → 拒绝策略处理。

第一步,线程池通过 submit() 提交任务。

ExecutorService threadPool = Executors.newFixedThreadPool(5);
threadPool.submit(() -> {
    System.out.println(Thread.currentThread().getName() + "\t" + "办理业务");
});

第二步,线程池会先创建核心线程来执行任务。

if (workerCountOf(c) < corePoolSize) {
    if (addWorker(command, true)) {
        return;
    }
}

第三步,如果核心线程都在忙,任务会被放入任务队列中。

workQueue.offer(task);

第四步,如果任务队列已满,且当前线程数量小于最大线程数,线程池会创建新的线程来处理任务。

if (!addWorker(command, false))

第五步,如果线程池中的线程数量已经达到最大线程数,且任务队列已满,线程池会执行拒绝策略。

handler.rejectedExecution(command, this);

第二种回答

第一步,创建线程池。

第二步,调用线程池的 execute()方法,准备执行任务。

  • 如果正在运行的线程数量小于 corePoolSize,那么线程池会创建一个新的线程来执行这个任务;
  • 如果正在运行的线程数量大于或等于 corePoolSize,那么线程池会将这个任务放入等待队列;
  • 如果等待队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么线程池会创建新的线程来执行这个任务;
  • 如果等待队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会执行拒绝策略。

第三步,线程执行完毕后,线程并不会立即销毁,而是继续保持在池中等待下一个任务。

第四步,当线程空闲时间超出指定时间,且当前线程数量大于核心线程数时,线程会被回收。

class ThreadPoolDemo {
    public static void main(String[] args) {
        // 创建一个线程池
        ExecutorService threadPool = new ThreadPoolExecutor(
                3, // 核心线程数
                6, // 最大线程数
                0, // 线程空闲时间
                TimeUnit.SECONDS, // 时间单位
                new LinkedBlockingQueue<>(10), // 等待队列
                Executors.defaultThreadFactory(), // 线程工厂
                new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
        );
        // 模拟 10 个顾客来银行办理业务
        try {
            for (int i = 1; i <= 10; i++) {
                final int tempInt = i;
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t" + "办理业务" + tempInt);
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

参数间的配合

线程池有 7 个参数,需要重点关注的有核心线程数、最大线程数、等待队列、拒绝策略。

①、corePoolSize:核心线程数,长期存活,执行任务的主力。

②、maximumPoolSize:线程池允许的最大线程数。

③、workQueue:任务队列,存储等待执行的任务。

④、handler:拒绝策略,任务超载时的处理方式。也就是线程数达到 maximumPoolSiz,任务队列也满了的时候,就会触发拒绝策略。

⑤、threadFactory:线程工厂,用于创建线程,可自定义线程名。

⑥、keepAliveTime:非核心线程的存活时间,空闲时间超过该值就销毁。

⑦、unit:keepAliveTime 参数的时间单位:

TimeUnit.DAYS; 天
TimeUnit.HOURS; 小时
TimeUnit.MINUTES; 分钟
TimeUnit.SECONDS; 秒
TimeUnit.MILLISECONDS; 毫秒
TimeUnit.MICROSECONDS; 微秒
TimeUnit.NANOSECONDS; 纳秒

能简单说一下参数之间的关系吗?

任务优先使用核心线程执行,满了进入等待队列,队列满了启用非核心线程备用,线程池达到最大线程数量后触发拒绝策略,非核心线程的空闲时间超过存活时间就被回收。

核心线程数不够会怎么进行处理?

  • 当提交的任务数超过了 corePoolSize,但是小于 maximumPoolSize 时,线程池会创建新的线程来处理任务。
  • 当提交的任务数超过了 maximumPoolSize 时,线程池会根据拒绝策略来处理任务。
posted @ 2025-04-21 20:13  kuki'  阅读(5)  评论(0)    收藏  举报