线程池参数策略

65 阅读3分钟

线程池

使用线程池用于维护一组线程,可以避免频繁的进行线程创建与销毁造成的浪费。需要使用线程的时候从线程池中取出就可以了。

案例

public class ExecutorDemo {
    public static void main(String[] args) {

        int corePoolSize = 5;
        int maximumPoolSize = 10;
        long keepAliveTime = 1000;
        TimeUnit unit = TimeUnit.SECONDS;

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, new LinkedBlockingDeque<>());

        for (int i = 0; i < 10; i++){
            threadPoolExecutor.submit(() -> {
                System.out.println(Thread.currentThread().getName() + "正在执行");
            });
        }

        threadPoolExecutor.shutdown();

    }
}

一般创建线程池都使用 ThreadPoolExecutor,可以更加灵活的控制参数,灵活的使用线程池。

参数说明

  1. 核心线程数:corePoolSize,线程池的核心线程数
  2. 最大线程数:maximumPoolSize,线程池的最大线程数
  3. 存活时间:keepAliveTime,超过核心线程数小于最大线程数的线程的存活时间
  4. 时间单位:存活时间的时间单位。
  5. 堵塞队列:blockedQueue,多余的任务排队
  6. 拒绝策略:RejectedHandler

线程池维护一组核心线程池数的线程,当有超过该线程数的任务时,会被放在堵塞队列中等待,如果任务太多,堵塞队列也满了的话,会判断当前的线程数是否小于最大的线程数,是的话就会继续创建线程。

当执行完成后,大于核心线程数的线程空闲时间的达到存活时间后,会进行销毁。

当创建到等于最大线程池数的线程之后,如果还有任务的出现,并且把阻塞队列也满了,此时就会使用拒绝策略。

  1. 核心线程数:线程池的核心线程数

I/O 密集型:使用对网络直接的传输,输入输出,对数据库操作等,这个操作可以设置较大的线程池数量。

CPU密集型:计算机应用的类型,为了可以充分的发挥CPU,线程池的数量一般为 CPU 的核的个数或倍数。

一般的情况下,假如CPU的核心数量为 N

CPU 密集型可以设置为 N + 1

I/O 密集型可以设置为 N 的倍数.

  1. 最大线程数:线程池的最大线程数

搭配核心线程数,保持应用使用的线程数不会超出系统的上限。

具体的数量,还是根据实际的业务逻辑,以及测试所得。

  1. 存活时间:keepAliveTime,超过核心线程数小于最大线程数的线程的存活时间

使用超过核心线程数的存放时间,一般短的任务可以设置较短的存活时间,长的任务设置较长的存放时间。

  1. 时间单位:存活时间的时间单位。

这个搭配存活时间使用,一般有毫秒,秒,分钟。

  1. 堵塞队列:多余的任务如何排队有界的阻塞队列一般使用 LinkedBlockQueue。无界的使用 sychronousQueue。

  2. 拒绝策略:RejectedHander,当任务太多会触发拒绝策略,默认的为 AbortPolicy() ,抛出异常的策略。