线程池的好处
- 降低资源消耗:重复利用同一个线程可以执行多个不同的任务(Runnable)
- 提高响应速度:线程池中拥有创建好的线程,拿过来就用,不用new再start
- 提高线程的可管理性:避免这边用一下new一个,那边又new一个
线程池的实现原理
- 提交任务流程
- 判断核心线程数是否满,不满创建新线程执行
- 若核心线程数是满的,判断工作队列是否满,不满进入队列
- 若工作队列也满,就看看是否可以创建临时线程
- 最后都不行,就用指定的拒绝策略
- 工作线程的一个执行流程
线程池的创建
- corePoolSize:可以使用
prestartAllCoreThreads()
方法,提前创建好 - 任务队列
- ArrayBlockingQueue:有界,数组
- LinkedBlockingQueue:有界,链表,吞吐量高于上者
- SynchronousQueueu:不存储元素的队列
- PriorityBlockingQueue:优先级、无限
- maximumPoolSize:使用无界队列的话就无效果了
- ThreadFactory:创建线程的工厂,guava工具类中有可以快速创建的类
- RejectedExecutionHandler:饱和策略
- AbortPolicy:直接抛异常
- CallerRunsPolicy:丢任务到线程池中的线程自己去执行
- DiscardOldestPolicy:丢弃最老的任务
- DiscardPolicy:直接丢弃当前新进任务
- keepAliveTime:工作线程的存活时间,任务执行时间较短的可以调大时间
- TimeUnit:指定上面时间的单位
提交任务
- execute:提交runnable
- submit:有返回值
关闭线程池
- shutdown
- 线程池状态置为shutdown
- 逐个中断运行中的线程(只是打标记)
- shutdownNow
- 线程池状态置为STOP
- 尝试停止或暂停任务
共性
建议使用有界队列
- Runtime.getRuntime().availableProcessors()方法获得当前设备的CPU个数
- CPU密集型:N+1
- IO密集型:2*N
线程池的监控
- 方法
- taskCount:需要执行任务的数量
- completedTaskCount:已经完成的
- largestPoolSize:是否满过
- getPoolSize:线程数
- getActiveCount:活动线程数
- 钩子
- beforeExecute
- afterExecute
- terminated