4、线程池相关(点个赞呗)
2020-07-08 18:35:36 0 举报
AI智能生成
java线程池多知识点
作者其他创作
大纲/内容
线程池相关
Callable、Future
概念
Callable<T>
定义一个任务,和Runnable中的run类似,不同之处在于call是异步的有返回值的任务
Future<V>
存储执行的将来才会产生的结果
简单使用
Callable+Future+线程池使用
FutureTask使用
注意点
Callable一般与线程池和Future一起使用
Future的get方法是阻塞的,直到有值获取到了才继续
FutureTask继承RunnableFuture接口,RunnableFuture接口继承Runnable和Future接口,该类可以作为一个任务使用
拓展
CompletableFuture
用来管理多个Future结果,然后返回
线程池(两种)
ThreadPoolExecutor
线程池维护着两个集合
线程集合
任务集合
任务进线程池处理顺序(execute方法)
1、初始,线程池为空
2、来n个任务启n个核心线程(核心线程数未满)
3、核心线程数满了,再来任务,任务进入任务队列中
4、任务队列满了,再来任务,启新线程处理它(未到最大线程数)
5、到最大线程数了,且任务队列满了,再来任务,执行拒绝策略处理
七个参数
int corePoolSize
核心线程数
int maximumPoolSize
最大线程数
long keepAliveTime
生存时间
TimeUnit unit
生存时间的单位(毫秒、纳秒、秒等)
BlockingQueue<Runnable> workQueue
任务队列,常用的几种
ArrayBlockingQueue(固定长度的任务)
LinkedBlockQueue(最大Integer.maxValue个任务)
SynchronousQueue(0个任务,就是指来个任务线程池必须去处理它,否则没处理完下一个任务加不进来)
TransferQueue(来个任务必须处理完了才走否则阻塞等着)
ThreadFactory threadFactory
线程工厂,定义产生什么样的线程,线程名叫什么等
实现ThreadFactory接口(实现newThread方法)
定义生成的线程名是什么,是不是Deamon,设置优先级Priority
RejectedExecutionHandler handler
拒绝策略(JDK提供四种,默认是AbortPolicy,支持自定义)
ThreadPoolExecutor.AbortPolicy
丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy
也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy
扔掉排队时间最久的任务
ThreadPoolExecutor.CallerRunsPolicy
由调用线程处理该任务
JDK提供的实现
SingleThreadPool
单线程的线程池,保证任务顺序执行
问题:为什么要有单线程的线程池?
1、线程池提供任务队列不需要自己去创建
2、线程池有自己的生命周期管理,不需要我们去维护
CacheThreadPool
无核心线程的线程池,来一个任务启一个线程,任务队列为SynchronousQueue
FixedThreadPool
指定一个固定大小单线程池,核心线程数=最大线程数
ScheduledThreadPool
定时任务线程池,复杂的定时任务框架用quartz
ThreadPoolExecutor源码重要参数
AtomicInteger ctl
高3位表示线程数,低29位表示worker数量(线程数)
线程池5种状态,按大小排序:
RUNNING(-1)< SHUTDOWN(0)< STOP(1)< TIDYING(2)< TERMINATED(3)
int runStateof(int c)
获取线程池状态,通过按位与操作,低29位将全部变成0
int workerCountof(int c)
获取线程池worker数量,通过按位与操作,高3位将全部变成0
int ctlof(int rs,int wc)
根据线程状态和线程池worker数量,生成ctl值
boolean runStateLessThan(int c,int s)
判断线程状态小于xx
boolean runStateLeast(int c,int s)
判断线程状态大于等于xx
Worker类
Runnable+AQS
中间有Thread变量需要执行,所以需要抢
addWorker方法
worker的count++,然后添加worker并start
疑问
1、不建议使用JDK自带的解决策略和线程池实现?
1、可能会造成任务队列非常长造成oom
2、默认的线程池命名无法帮助排查问题
2、线程池的线程数量估算
N(threads)= cpu核数 * 期望cpu使用率 * (1 + 等待时间/计算时间)
3、Cache vs Fixed
任务量忽高忽低就Cache,比较平稳则Fixed,但应该都不用,自己估算进行精确定义。
4、concurrent vs parallel
并发是指认为提交,并行是指任务执行,并行是并发的子集
ForkJoinPool
特性
分解汇总任务(把大任务切成小任务,最后汇总任务)
用很少的线程可以执行很多的任务(子任务)ThreadPoolExecutor做不到先执行子任务
cpu密集型
实现
WorkStealingPool
每个线程维护一个自己的任务队列,当自己任务队列为空时,从别的线程的任务队列尾巴获取任务加到自己的任务队列中
原理
1、多个work queue
2、采用work stealing算法
一般执行ForkJoinTask的实现RecursiveAction任务(不带返回值的任务)
ThreadPoolExecutor、ForkJoinPool区别
前者共享一个任务队列,后者每个线程维护一个任务队列
0 条评论
下一页