ThreadPoolExecutor 配置详解

一,ThreadPoolExecutor介绍

ThreadPoolExecutor 是Java原生的线程池,我们只需要简单配置一下就可以使用了

二,线程池配置详解

ExecutorService exe = new ThreadPoolExecutor(
            //核心线程池大小
            CORE_POOL_SIZE,
            //最大线程池大小
            MAXIMUM_POOL_SIZE,
            //线程最大空闲时间
            KEEP_ALIVE_TIME,
            //时间单位
            TimeUnit.MILLISECONDS,
            //线程等待队列
            new LinkedBlockingQueue<>(1024),
            //线程创建工厂 (可选,默认值: Executors.defaultThreadFactory())
            r -> new Thread(r),
            //拒绝策略 (可选,默认值: AbortPolicy())
            new ThreadPoolExecutor.AbortPolicy());

1. corePoolSize

线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;

如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;

如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程。

2. maximumPoolSize

线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,前提是当前线程数小于maximumPoolSize

3. keepAliveTime

线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间。默认情况下,该参数只在线程数大于corePoolSize时才有用

4.TimeUnit

keepAliveTime的时间单位

TimeUnit.DAYS          //天
TimeUnit.HOURS         //小时
TimeUnit.MINUTES       //分钟
TimeUnit.SECONDS       //秒
TimeUnit.MILLISECONDS  //毫秒

5.workQueue

workQueue必须是BlockingQueue阻塞队列。当线程池中的线程数超过它的corePoolSize的时候,线程会进入阻塞队列进行阻塞等待。通过workQueue,线程池实现了阻塞功能

常用的BlockingQueue

ArrayBlockingQueue

数组结构组成有界阻塞队列。

先进先出原则,初始化必须传大小,take和put时候用的同一把锁
LinkedBlockingQueue

链表结构组成的有界阻塞队列

先进先出原则,初始化可以不传大小,put,take锁分离

PriorityBlockingQueue

支持优先级排序的无界阻塞队列,

排序,自然顺序升序排列,更改顺序:类自己实现compareTo()方法,初始化PriorityBlockingQueue指定一个比较器Comparator

DelayQueue

使用了优先级队列的无界阻塞队列

支持延时获取,队列里的元素要实现Delay接口。DelayQueue非常有用,可以将DelayQueue运用在以下应用场景。

缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了。

还有订单到期,限时支付等等。

SynchronousQueue

不存储元素的阻塞队列

每个put操作必须要等take操作

LinkedTransferQueue

链表结构组成的界阻塞队列

Transfer,tryTransfer,生产者put时,当前有消费者take,生产者直接把元素传给消费者

LinkedBlockingDeque

链表结构组成的双向阻塞队列

可以在队列的两端插入和移除,xxxFirst头部操作,xxxLast尾部操作。工作窃取模式。

6.ThreadFactory

创建线程的工厂,通过自定义的线程工厂可以给每个新建的线程设置一个具有识别度的线程名

Executors静态工厂里默认的threadFactory,线程的命名规则是“pool-数字-thread-数字”

7.RejectedExecutionHandler

线程池的饱和策略,当阻塞队列满了,且没有空闲的工作线程,如果继续提交任务,必须采取一种策略处理该任务,线程池提供了4种策略:

(1)AbortPolicy:直接抛出异常,默认策略;

(2)CallerRunsPolicy:用调用者所在的线程来执行任务;

(3)DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务;

(4)DiscardPolicy:直接丢弃任务;

当然也可以根据应用场景实现RejectedExecutionHandler接口,自定义饱和策略,如记录日志或持久化存储不能处理的任务。

三,合理的配置线程池

a. 区分任务类别

      计算密集型:计算机的cpu数或计算机的cpu数+1(应付页缺失)

      IO密集型:计算机的cpu数*2

      混合型:拆分成计算密集型,IO密集型

Runtime.getRuntime().availableProcessors();获取当前机器中的cpu核心个数

b.尽量有界队列,不要使用无界队列

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值