并发编程(十七):Excutor与ThreadPoolExcutor
学习资料
《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可以创建多种线程池:
WorkStealingPoolScheduledThreadPool- 和以下三种
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)操作,反之亦然


浙公网安备 33010602011771号