线程池
线程池简介
线程池(Thread Pool):把一个或多个线程通过统一的方式进行调度和重复使用的技术,避免了因为线程过多而带来使用上的开销。
- 优点:
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
- 提高线程的可管理性。
线程池创建方式
- newCachedThreadPool:创建一个可缓存线程池
- newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数。
- newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
- newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务
核心参数:
- corePoolSize: 线程池核心线程数最大值
- maximumPoolSize: 线程池最大线程数大小
- keepAliveTime: 线程池中非核心线程空闲的存活时间大小
- unit: 线程空闲存活时间单位
- workQueue: 存放任务的阻塞队列
- threadFactory: 用于设置创建线程的工厂,可以给创建的线程设置有意义的名字,可方便排查问题。
- handler: 线城池的饱和策略事件,主要有四种类型。
四种拒绝策略:
1、DiscardPolicy():丢弃掉该任务但是不抛出异常,不推荐这种(导致使用者没觉察情况发生)
2、DiscardOldestPolicy():丢弃队列中等待最久的任务,然后把当前任务加入队列中。
3、AbortPolicy():丢弃任务并抛出 RejectedExecutionException 异常(默认)。
4、CallerRunsPolicy():由主线程负责调用任务的run()方法从而绕过线程池直接执行,既不抛弃 任务也不抛出异常(当最大线程数满了,任务队列中也满了,再来一个任务,由主线程执行)
线程池执行流程图
如何确定线程池线程数目?
多线程执行的任务为类型分为CPU密集和I/O密集
CPU密集型:主要消耗cpu资源,线程数计算n(cpu核心数)+1,比cpu核心数多出来一个是为了防止线程偶发的缺页中断,或其他原因导致的任务暂停。
I/O密集型:系统大部分时间是在进行任务交互,线程在处理I/O时不会占用cpu来处理,所以设置为2n
详细:https://blog.csdn.net/yuyan_jia/article/details/120298564
线程池的工作队列
线程池都有哪几种工作队列?
- ArrayBlockingQueue
- LinkedBlockingQueue
- DelayQueue
- PriorityBlockingQueue
- SynchronousQueue
ArrayBlockingQueue
ArrayBlockingQueue(有界队列)是一个用数组实现的有界阻塞队列,按FIFO排序量。
LinkedBlockingQueue
LinkedBlockingQueue(可设置容量队列)基于链表结构的阻塞队列,按FIFO排序任务,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE,吞吐量通常要高于ArrayBlockingQuene;newFixedThreadPool线程池使用了这个队列
DelayQueue
DelayQueue(延迟队列)是一个任务定时周期的延迟执行的队列。根据指定的执行时间从小到大排序,否则根据插入到队列的先后排序。newScheduledThreadPool线程池使用了这个队列。
PriorityBlockingQueue
PriorityBlockingQueue(优先级队列)是具有优先级的无界阻塞队列;
SynchronousQueue
SynchronousQueue(同步队列)一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQuene,newCachedThreadPool线程池使用了这个队列。
** 公众号