jvm之线程池
java线程池实现继承关系
Executor==>ExecutorService-->AbstractExecutorService==>ThreadPoolExecutor
- Executor-接口
- execute,执行某个Runnable实现类
- ExecutorService-接口,较Executor提供了更多的功能
- submit,执行Callable实现类,返回值通过Future返回
- AbstractExecutorService-线程池抽象类
- 实现了submit方法
- 在执行submit方法前会将Callable转为FutureTask类,然后调用execute方法执行
- FutureTask是Runnable的实现类
- 线程池基本都继承该抽象类
线程池实现类
ThreadPoolExecutor
- 实现了execute方法,在该方法中判断核心线程数
- 如果小于核心线程数,则通过addWorker新增核心线程执行该command
- 如果小于核心线程数,则将command添加至任务队列中
- 如果添加队列失败,则继续通过addWorker新增非核心线程
- 如果新增线程失败,则执行拒绝策略
- addWorker是添加线程的方法
- 在该方法中会创建一个Worker实例,Worker是aqs的实现类
- Worker构造方法中通过
this.thread = getThreadFactory().newThread(this);
维护一个线程及第一个task - 通过Worker获取到创建的thread,执行start方法,故会执行Worker的run方法
- 在run中执行runWorker方法,在该方法中会从BlockingQueue中获取task循环执行
- 如果BlockingQueue中为空,则会阻塞,直到有数据后返回
- 获取到task,继续执行
ScheduledThreadPoolExecutor 任务定时执行器,继承自ThreadPoolExecutor
- ScheduledThreadPoolExecutor的submit及execute方法执行的均为schedule方法
- 在delayedExecute中将task封装为RunnableScheduledFuture调用delayedExecute方法
- 在delayedExecute方法中会向super.getQueue()中添加该task
- super.queue为ScheduledThreadPoolExecutor构造方法中调用父类ThreadPoolExecutor构造方法传入的DelayedWorkQueue
- DelayedWorkQueue通过
RunnableScheduledFuture<?>[]
数组维护task执行顺序,在ThreadPoolExecutor 获取task时,如果未到时间则等待 - ScheduledFutureTask中的heapIndex为该future在
RunnableScheduledFuture<?>[]
数组中的索引 - 向DelayedWorkQueue添加task
- 如果数据中已存在task,则在添加时,会依次比较执行时间,将新添加的task保存到对应索引值上
- 如果将该task添加到 0 索引位置上,则立即唤醒因获取不到task而wait的线程执行该task
- take方法收到信息后,继续执行,获取第一个task并return
- 如果take方法未获取到,则直接await
- 如果take方法获取到的未到时间,则通过
available.awaitNanos(delay);
修改delay时长
- 总结ScheduledThreadPoolExecutor比ThreadPoolExecutor的区别是维护了一个DelayedWorkQueue
ForkJoinPool-分而治之线程池
- ForkJoinPool使用demo具体见java线程池之ForkJoinPool
ThreadFactory
用于创建thread,在newThread方法中可进行一些自定义的操作,如threadlocal赋值,自定义thread name,指定threadgroup ,设置thread stack size等
ThreadGroup
在创建thread时可以指定threadgroup,用于批量管控thread,比如可通过group.interrupt();打断所有的thread