4、线程池相关(点个赞呗)
2020-07-08 18:35:36 0 举报
AI智能生成
java线程池多知识点
作者其他创作
大纲/内容
Callable、Future
概念
Callable<T>
定义一个任务,和Runnable中的run类似,
不同之处在于call是异步的有返回值的任务
不同之处在于call是异步的有返回值的任务
Future<V>
存储执行的将来才会产生的结果
简单使用
Callable+Future+线程池使用
FutureTask使用
注意点
Callable一般与线程池和Future一起使用
Future的get方法是阻塞的,直到有值获取到了才继续
FutureTask继承RunnableFuture接口,RunnableFuture接
口继承Runnable和Future接口,该类可以作为一个任务使用
口继承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,支持自定义)
认是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 条评论
下一页