线程池
-
new Thread弊端
- 每次new Thread新建对象,性能差
- 线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或OOM
- 缺少更多功能,如更多执行,定期执行,线程中断
-
线程池的好处
- 重用存在的线程,减少对象的创建,消亡的开销,性能好
- 提高系统资源利用率,同时可以避免过多资源竞争,避免阻塞
- 提供定时执行,定期执行,单线程,并发数控制等功能
-
ThreadPoolExecutor
-
corePoolSize: 核心线程数量
-
maximumPoolSize: 线程最大线程数
-
workQueue:阻塞队列,存储等待执行的任务,如果任务提交速度持续大余任务处理速度,会造成队列大量阻塞。因为队列很大,很有可能在拒绝策略前,内存溢出。是其劣势
-
keepAliveTime :线程池没有任务执行时最多保持多久时间终止
-
unit:keepALiveTime的时间单位
-
threadFactory:线程工厂,用来创建线程
-
rejectHandler: 当拒绝处理任务时的策略
-
参数之间的关系
-
运行的线程 < corePoolSize 创建新线程来运行任务(即使线程池中的其他线程是空闲的)
-
corePoolSize <= 线程池中的线程数量 < maximumPoolSize时,只有workQueue满的时候创建新的线程去执行任务
-
corePoolSize = maximumPoolSize 创建的线程池大小固定,此时有新的任务提交,如果workQueue未满,则将线程放入到workQueue中,等待有空闲的线程执行,若workQueue已满,则指定策略去执行
-
-
线程池的几种状态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T6gZbghR-1585933125597)(…/pic/ThreadPoolExecutor.png)]-
RUNNING:Running状态下能接收新的任务,也能处理阻塞队列中的任务
-
SHUTDOWN:SHUTDOWN状态下不能再接受新的任务,但可以处理阻塞队列中已经保存的任务
-
STOP:不接受新的任务,也不处理阻塞队列中的任务,会中断正在处理任务的线程
-
TIDYING:如果阻塞队列为空,工作线程数量也为0,进入该状态
-
TERMINATED:在TIDYING之后进入此状态
-
-
方法:
- execute():提交任务,交给线程池执行
- submit():提交任务,能返回执行结果 execute+future
- shutdown():关闭线程池,等待任务都执行完毕
- shutdownNow():关闭线程池,不等待任务执行完
- getTaskCount(): 获得线程池已执行和未执行的任务总数
- getCompletedTaskCount(): 获得已完成的任务数量
- getPoolSize():获得线程池当前的线程数量
- getActiveCount(): 当前线程中正在执行任务的线程数量
-
Executor框架接口
- Executors.newCachedThreadPool
- 创建一个可缓存的线程池,如果线程池长度超过了需要的长度,可以灵活回收空闲的线程
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
- Executors.newFixedThreadPool
- 创建一个定长的线程池,可控制线程的最大并发数,超出的线程会在队列中等待
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
- Executors.newScheduledThreadPool
- 创建一个定长的线程池,支持定时以及周期性的任务执行
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize);
- Executors.newSingleThreadExecutor
- 创建一个单线程化的线程池,它只会用唯一的一个工作线程去执行任务,保证任务以指定顺序去执行
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
- Executors.newCachedThreadPool
-
线程池的合理配置
-
CPU密集型任务,尽量压榨CPU,参考值可设为NCPU+1
-
IO密集型任务,参考值可以设置为2*NCPU
-
-