合理使用线程池的好处:
① 降低资源消耗
② 提高响应速度
③ 提高线程的可管理性
当一个新任务到线程池时,线程池的处理流程:
① 线程池判断核心线程池中的线程是否都在执行任务,如不是,则创建一个新的工作线程来执行这个任务,否则进入下一流程
② 线程池判断工作队列是否已满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下一个流程。
③ 线程池判断线程池里的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果满了,则由饱和策略处理这一个任务。默认饱和策略为抛出异常。
参数:
① corePoolSize: 核心线程池大小,当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即时其它空闲线程能够执行任务也会创建新线程,知道需要执行的任务数大于核心线程数。 prestartAllCoreThreads() 线程池会提前创建并启动所有核心线程
② runnableTaskQueue(任务队列)
1. ArrayBlockingQueue: 基于数组的有界队列 FIFO
2. LinkedBlockingQueue: 基于链表 FIFO 吞吐量高于ArrayBlockingQueue
Executors.newFixedThreadPool(); 最大线程数=核心线程数 最大线程数再大也用不到...
3. SynchronousQueue: 不存储元素的队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞 状态,吞吐量更高。
Executors.newCachedThreadPoolk(); 核心线程数=0 最大线程数 Integer.MAX_VALUE
③ maximumPoolSize
④ ThreadFactory
用于设置创建线程的工程
⑤ RejectedExecutionHandler (饱和策略)
1. AbortPolicy: 直接抛出异常 默认
2. CallerRunsPolicy: 只要调用者线程来运行任务
3. DiscardOldestPolicy: 丢弃队列里最近的一个任务,并执行当前任务
4. DiscardPolicy: 不处理,丢弃掉
关闭线程池
① shutdown(): 只是将线程池的状态设置为SHUTDOWN,然后中断所有没有正在执行任务的线程
② shutdownNow(): 首先将线程池的状态设为STOP,然后尝试停止所有正在执行或暂停任务的线程,并返回等待执行任务的列表。
CPU 密集型 尽量少的线程 cpu+1
cpu利用率较高,(复杂运算、逻辑处理)
IO密集型 n*2
cpu利用率较低,程序中存在大量的I/O操作占用时间,导致线程空余时间出来
高并发,任务执行时间段的业务,线程池线程数可以设置为CPU核数+1,减少线程池上下文切换
并发不高,任务执行时间长的业务,再次进行分析