常用参数
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)
- corePoolSize:表示常驻核心线程数。如果等于0,则任务执行完之后,没有任何请求进入时销毁线程池的线程。如果大于0,即使本地任务执行完毕,核心线程也不会被销毁
- maximumPoolSize:表示线程池能够创建的最大线程数。如果maximumPoolSIze和corePoolSize相等,即是固定大小线程池,例如:newFixedThreadPool
- keepAliveTime:表示线程池中的线程空闲时间,当空闲时间达到keepAliveTime值时,线程会被销毁,直到只剩下corePoolSize个线程为止。默认情况下,只有当maximumPoolSize大于corePoolSize该值才会起作用。当ThreadPoolExecutor的allowCoreThreadTImeOut变量设置为true的时候,核心线程也会被回收
- unit:表示时间单位,通常是TimeUnit.SECONDS
- workQueue:表示缓存队列。当请求的线程数大于maximumPoolSize时,线程进入BlockingQueue阻塞队列
- threadFactory:线程工厂
- handler:表示执行拒绝策略的对象。当超过workQueue的时候,可以通过该策略处理请求。JDK提供的策略有:AbortPolicy(直接抛出异常),CallerRunsPolicy(只用调用者所在线程来运行任务),DiscardOldestPolicy(丢弃队列里最近的一个任务,并执行当前任务),DiscardPolicy(不处理,丢弃掉)。用户友好的拒绝策略:保存到数据库进行削峰填谷,在空闲时再提取出来执行。转向某个提示页面。打印日志
基本原理
- 当有任务提交到线程池中时,创建线程执行任务,任务执行完成后线程回到线程池中等待
- 当线程池中的线程数量等于corePoolSize时,此时任务进入队列等待
- 如果队列中已满,且当前线程池中的线程数量小于maximumPoolSize,创建线程执行任务,执行完成后线程回到线程池中等待keepAliveTime后销毁
- 如果队列已满,且当前线程池中的线程数量大于maximumPoolSize,触发拒绝策略
线程池分类
Executors.newCachedThreadPool:maximumPoolSize最大可以到
Integer.MAX_VALUE,是高度可伸缩的线程池。keepAliveTime默认为60秒,工作线程处于空闲状态,则回收工作线程。如果任务数增加,再次创建出新的线程处理任务 Executores.newScheduledThreadPool:线程数最大至Integer.MAX_VALUE,支持定时及周期性任务执行。其不回收工作线程 Executors.newSingleThreadExecutor:创建一个单线程的线程池,相当于单线程串行执行所有任务,保证按任务的提交顺序一次执行 Executors.newFixedThreadPool:输入的参数即是固定线程数,核心线程数也是最大线程数,不存在空闲线程,所以keepAliveTime等于0 Executors.newWorkStealingPool:JDK8中引入,创建持有足够线程的线程池支持给定的并行度,并通过使用多个队列减少竞争,此构造方法中把CPU数量设置为默认并行度
如何设置线程池大小
CPU密集型:CPU核数 + 1。即使当CPU密集型的线程偶尔由于页确实故障或者其他原因暂停时,这个“额外”的线程也能确保CPU的时钟周期不会被浪费 IO密集型:CPU核数 期望CPU使用率 [1 + (I/O耗时)/ (CPU耗时)]

