Java并发编程 10 线程池
来源:互联网 发布:为什么淘宝没有gta5 编辑:程序博客网 时间:2024/05/22 13:59
线程池的作用
减少资源的开销:减少了每次创建线程、销毁线程的开销。
提高响应速度: 每次请求到来时,由于线程的创建已经完成,故可以直接执行任务,因此提高了响应速度。
提高线程的可管理性: 线程是一种稀缺资源,若不加以限制,不仅会占用大量资源,而且会影响系统的稳定性。
因此,线程池可以对线程的创建与停止、线程数量等等因素加以控制,使得线程在一种可控的范围内运行,不仅能保证系统稳定运行,而且方便性能调优。
线程池的实现原理
线程池一般由两种角色构成:多个工作线程 和 一个阻塞队列。
工作线程 :工作线程是一组已经处在运行中的线程,它们不断地向阻塞队列中领取任务执行。
阻塞队列 :阻塞队列用于存储工作线程来不及处理的任务。当工作线程都在执行任务时,到来的新任务就只能暂时在阻塞队列中存储。
ThreadPoolExecutor的使用
创建线程池,可以通过如下代码即可创建一个线程池:
new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, runnableTaskQueue, handler);
提交任务
可以向ThreadPoolExecutor提交两种任务:Callable和Runnable。
Callable 该类任务有返回结果,可以抛出异常。 通过submit函数提交,返回Future对象。 可通过get获取执行结果。Runnable 该类任务只执行,无法获取返回结果,并在执行过程中无法抛异常。 通过execute提交。
关闭线程池
关闭线程池有两种方式:shutdown和shutdownNow,关闭时,会遍历所有的线程,调用它们的interrupt函数中断线程。但这两种方式对于正在执行的线程处理方式不同。
shutdown() 仅停止阻塞队列中等待的线程,那些正在执行的线程就会让他们执行结束。shutdownNow() 不仅会停止阻塞队列中的线程,而且会停止正在执行的线程。
ThreadPoolExecutor运行机制
当有请求到来时:若当前实际线程数量 少于 corePoolSize,即使有空闲线程,也会创建一个新的工作线程;
若当前实际线程数量处于corePoolSize和maximumPoolSize之间,并且阻塞队列没满,则任务将被放入阻塞队列中等待执行;
若当前实际线程数量 小于 maximumPoolSize,但阻塞队列已满,则直接创建新线程处理任务;
若当前实际线程数量已经达到maximumPoolSize,并且阻塞队列已满,则使用饱和策略。
设置合理的线程池大小
任务一般可分为:CPU密集型、IO密集型、混合型,对于不同类型的任务需要分配不同大小的线程池。
CPU密集型任务 : 尽量使用较小的线程池,一般为CPU核心数+1。 因为CPU密集型任务使得CPU使用率很高,若开过多的线程数,只能增加上下文切换的次数,因此会带来额外的开销。
IO密集型任务 : 可以使用稍大的线程池,一般为2*CPU核心数。 IO密集型任务CPU使用率并不高,因此可以让CPU在等待IO的时候去处理别的任务,充分利用CPU时间。
混合型任务 : 可以将任务分成IO密集型和CPU密集型任务,然后分别用不同的线程池去处理。 只要分完之后两个任务的执行时间相差不大,那么就会比串行执行来的高效。 因为如果划分之后两个任务执行时间相差甚远,那么先执行完的任务就要等后执行完的任务,最终的时间仍然取决于后执行完的任务,而且还要加上任务拆分与合并的开销,得不偿失。
我的总结
我之前就专门思考过线程池的size问题,因为当时是计算密集型的计算,所以size设置为CPU的core的数量。
- Java并发编程 10 线程池
- java并发编程:线程池
- Java并发编程:线程池
- Java并发编程 线程池
- java并发编程---线程池
- Java并发编程:线程池
- Java并发编程:线程池
- 【Java并发编程】线程池
- java并发编程--线程池
- java并发编程-java线程池
- 10 Java并发编程5-线程池的使用
- java并发编程--线程池初步
- java并发编程(6)--线程池
- Java并发编程:线程池的使用
- Java并发编程:线程池的使用
- Java并发编程:线程池的使用
- Java并发编程:线程池的使用
- Java并发编程:线程池的使用
- C++ 基础知识四
- Angular 4.x 学习导引
- pc 电脑web浏览器js通过usb控制安卓手机打电话挂电话
- Codeforces 315C Sereja and Contest【思维】
- MySQL 忘记密码:skip-grant-tables
- Java并发编程 10 线程池
- 关于实模式下汇编伪指令assume的个人理解
- java定时schedule(task,time)
- sql报错注入总结【积累中】
- Java中线程池的种类
- Codeforceds 315D Sereja and Periods【思维+Dp】
- bzoj3730震波
- Java中普通代码块,构造代码块,静态代码块区别及代码示例
- C语言实验——从大到小输出a、b、c(选择结构)