学习资料
《Java并发编程的艺术》第10章 10.1~10.2
1.Excutor简介
从JDK 5开始,把工作单元与执行机制分离开来。工作单元包括 Runnable 和 Callable ,而执行机制由 Executor 框架提供
1.1 两级调度模型
在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程,操作系统内核将这些线程映射到
硬件处理器上:
1.2 Executor框架的结构和成员
结构
主要由三大部分组成:
- 任务:Runnable 接口或 Callable 接口
- 任务的执行:核心接口Executor ,子接口
ExcutorService
接口,子接口实现类:ThreadPoolExecutor
和ScheduledThreadPoolExecutor
- 异步计算结果:Future 和实现类 FutureTask 类
相关类和接口:
Executor框架使用流程:
submit()
返回Future接口,execut()
无返回值Future.get()
等待任务完成,Future.cancel()
取消任务执行
成员
-
ThreadPoolExecutor:线程池核心实现类(后有详解)
可用工厂类Executors创建,有三种类型:
SingleThreadExecutor
,FixedThreadPool
,CachedThreadPool
-
ScheduledThreadPoolExecutor:
可用工厂类Executors创建,可创建两种类型:
-
ScheduledThreadPoolExecutor
:多个后台线程 -
SingleThreadScheduledExecutor
:单个后台线程
-
-
Future接口:表示异步计算结果,
submit()
返回 -
Runnable接口和Callable接口 :都可以被工作线程执行
除了可以自己创建实现Callable接口的对象外,还可以使用工厂类Executors来把一个
Runnable包装成一个Callable:
public static Callable<Object> callable(Runnable task); public static <T> Callable<T> callable(Runnable task,T result); //result为返回的内容
2.ThreadPoolExecutor详解
Executors可以创建多种线程池:
WorkStealingPool
ScheduledThreadPool
- 和以下三种
2.1 FixedThreadPool
可重用固定线程数线程池,核心数=最大线程数
内部使用LinkedBlockingQueue
无界队列,keepAliveTime(0L)和maximumPoolSize无效,不会拒绝任务
运行示意图:
2.2 SingleThreadExecutor
使用单个worker线程的Executor,corePoolSize=maximumPoolSize=1
内部使用LinkedBlockingQueue
无界队列
运行示意图:
2.3 CachedThreadPool
会根据需要创建新线程的线程池,相当于没有使用线程池
源码如下:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
-
corePoolSize被设置为0,即corePool为空;
-
maximumPoolSize被设置为 Integer.MAX_VALUE,即maximumPool是无界的;
-
keepAliveTime设置为60L,空闲超过60秒的线程会被终止;
SynchronousQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS)
-
内部使用 SynchronousQueue 作为线程池的工作队列,不保存元素;
运行示意图:
每个插入(offer
)操作必须等待另一个线程的对应移除(poll
)操作,反之亦然