目录
本文摘自java并发编程的艺术(本文摘出来用于本人学习)
在
Java
中,使用
线
程来异步
执
行任
务
。
Java
线
程的
创
建与
销
毁
需要一定的开
销
,如果我
们
为
每一个任
务创
建一个新
线
程来
执
行,
这
些
线
程的
创
建与
销
毁
将消耗大量的
计
算
资
源。同
时
,
为
每一个任
务创
建一个新
线
程来
执
行,
这
种策略可能会使
处
于高
负
荷状
态
的
应
用最
终
崩
溃
。
Java的线程既是工作单元,也是执行机制。
从
JDK 5
开始,把工作
单
元与
执
行机制分离开
来。工作
单
元包括
Runnable
和
Callable
,而
执行机制由Executor框架提供
Executor框架简介
在
HotSpot VM
的
线程模型中,
Java
线
程(
java.lang.Thread
)被一
对
一映射
为
本地操作系
统线
程。
Java
线
程启
动时
会
创
建一个本地操作系
统线
程;当
该
Java
线
程
终
止
时
,
这
个操作系
统线
程
也会被回收。操作系
统
会
调
度所有
线
程并将它
们
分配
给
可用的
CPU
。
在上
层
,
Java
多线程程序通常把应用分解为若干个任务
,然后使用用
户级的调度器
(Executor框架)将这些任务映射为固定数量的线
程;在底
层,操作系统内核将这些线程映射到
硬件处理器上

Executor框架的结构
Executor框架主要由3大部分组成如下。
-
· 任 务 。包括被 执 行任 务 需要 实现 的接口: Runnable 接口或 Callable 接口。
-
任 务 的 执 行。包括任 务执 行机制的核心接口 Executor ,以及 继 承自 Executor 的ExecutorService 接口。 Executor 框架有两个关 键类实现 了 ExecutorService 接口( ThreadPoolExecutor 和 ScheduledThreadPoolExecutor )。
- ·异步计算的结果。包括接口Future和实现Future接口的FutureTask类。
Executor
是一个接口,它是
Executor
框架的基
础
,它将任
务
的提交与任
务
的
执
行分离开
来。
- ·ThreadPoolExecutor是线程池的核心实现类,用来执行被提交的任务。
- ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行命令,或者定期执 行命令。ScheduledThreadPoolExecutor比Timer更灵活,功能更强大。 ·Future接口和实现
- Future接口的FutureTask类,代表异步计算的结果。
- Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor或Scheduled- ThreadPoolExecutor执行。
如何使用Excutor框架?
主
线
程首先要
创
建
实现
Runnable
或者
Callable
接口的任
务对
象。工具
类
Executors
可以把一
个
Runnable
对
象封装
为
一个
Callable
对
象(
Executors.callable
(
Runnable task
)或
Executors.callable
(
Runnable task
,
Object resule
))。
然后可以把
Runnable
对
象直接交
给
ExecutorService
执
行(
ExecutorService.execute
(
Runnable
command
));或者也可以把
Runnable
对
象或
Callable
对
象提交
给
ExecutorService
执
行(
Executor-Service.submit
(
Runnable task
)或
ExecutorService.submit
(
Callable<T>task
))。
如果
执
行
ExecutorService.submit
(
…
),
ExecutorService
将返回一个
实现
Future
接口的
对
象
(到目前
为
止的
JDK
中,返回的是
FutureTask
对
象)。由于
FutureTask
实现
了
Runnable
,程序
员
也可
以
创
建
FutureTask
,然后直接交
给
ExecutorService
执
行。
最后,主
线
程可以
执
行
FutureTask.get()
方法来等待任
务执
行完成。主
线
程也可以
执
行
FutureTask.cancel
(
boolean mayInterruptIfRunning
)来取消此任
务
的
执
行。
Excutor框架的成员
Executor
框架的主要成
员
:
ThreadPoolExecutor
、
ScheduledThreadPoolExecutor
、
Future
接口、
Runnable
接口、
Callable
接口和
Executors
。
(
1
)
ThreadPoolExecutor
ThreadPoolExecutor
通常使用工厂
类
Executors
来
创
建。
Executors
可以
创
建
3
种
类
型的
ThreadPoolExecutor:SingleThreadExecutor、FixedThreadPool和CachedThreadPool。
1
)
FixedThreadPool
。下面是
Executors
提供的,
创
建使用固定
线
程数的
FixedThreadPool
的
API
public static ExecutorService newFixedThreadPool(int nThreads)public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactorythreadFacto
FixedThreadPool
适用于
为
了
满
足
资
源管理的需求,而需要限制当前
线
程数量的
应
用
场
景,它适用于
负载
比
较
重的服
务
器。
2)
SingleThreadExecutor
。下面是
Executors
提供的,
创
建使用
单
个
线
程的
SingleThread-
Executor
的
API
。
public static ExecutorService newSingleThreadExecutor()public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory)
SingleThreadExecutor
适用于需要保
证顺
序地
执
行各个任
务
;并且在任意
时间
点,不会有多
个
线
程是活
动
的
应
用
场
景。
3
)
CachedThreadPool
。下面是
Executors
提供的,
创
建一个会根据需要
创
建新
线
程的
CachedThreadPool
的
API
。
public static ExecutorService newCachedThreadPool()public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory)
CachedThreadPool
是大小无界的
线
程池,适用于
执
行很多的短期异步任
务
的小程序,或者
是
负载较轻
的服
务
器。
(
2
)
ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor
通常使用工厂
类
Executors
来
创
建。
Executors
可以
创
建
2
种
类
型的
ScheduledThreadPoolExecutor
,如下。
- ScheduledThreadPoolExecutor。包含若干个线程的ScheduledThreadPoolExecutor。
- SingleThreadScheduledExecutor。只包含一个线程的ScheduledThreadPoolExecutor。
下面是工厂
类
Executors
提供的,
创
建固定个数
线
程的
ScheduledThreadPoolExecutor
的
API
。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize,threadFactory)
ScheduledThreadPoolExecutor
适用于需要多个后台
线
程
执
行周期任
务
,同
时为
了
满
足
资
源
管理的需求而需要限制后台
线
程的数量的
应
用
场
景。下面是
Executors
提供的,
创
建
单
个
线
程
的
SingleThreadScheduledExecutor
的
API
。
public static ScheduledExecutorService newSingleThreadScheduledExecutor()public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
SingleThreadScheduledExecutor
适用于需要
单
个后台
线
程
执
行周期任
务
,同
时
需要保
证顺
序地
执
行各个任
务
的
应
用
场
景。
(
3
)
Future
接口
Future
接口和
实现
Future
接口的
FutureTask
类
用来表示异步
计
算的
结
果。当我
们
把
Runnable
接口或
Callable
接口的
实现类
提交(
submit
)
给
ThreadPoolExecutor
或
ScheduledThreadPoolExecutor
时
,
ThreadPoolExecutor
或
ScheduledThreadPoolExecutor
会向我
们返回一个
FutureTask
对
象
<T> Future<T> submit(Callable<T> task)<T> Future<T> submit(Runnable task, T result)Future<> submit(Runnable task)
有一点需要
读
者注意,到目前最新的
JDK 8
为
止,
Java
通
过
上述
API
返回的是一个
FutureTask
对
象。但从
API
可以看到,
Java
仅仅
保
证
返回的是一个
实现
了
Future
接口的
对
象。在将
来的
JDK
实现
中,返回的可能不一定是
FutureTask
。
(
4
)
Runnable
接口和
Callable
接口
Runnable
接口和
Callable
接口的
实现类
,都可以被
ThreadPoolExecutor
或
Scheduled-
ThreadPoolExecutor
执
行。它
们
之
间
的区
别
是
Runnable
不会返回
结
果,而
Callable
可以返回
结
果
除了可以自己
创
建
实现
Callable
接口的
对
象外,
还
可以使用工厂
类
Executors
来把一个
Runnable
包装成一个
Callable
。
下面是
Executors
提供的,把一个
Runnable
包装成一个
Callable
的
API
。
public static Callable<Object> callable(Runnable task) // 假 设 返回 对 象 Callable1
下面是Executors提供的,把一个Runnable和一个待返回的结果包装成一个Callable的API。
public static <T> Callable<T> callable(Runnable task, T result) // 假 设 返回 对象Callable2
前面
讲过
,当我
们
把一个
Callable
对
象(比如上面的
Callable1
或
Callable2
)提交
给
ThreadPoolExecutor
或
ScheduledThreadPoolExecutor
执
行
时
,
submit
(
…
)会向我
们
返回一个
FutureTask
对
象。我
们
可以
执
行
FutureTask.get()
方法来等待任
务执
行完成。当任
务
成功完成后
FutureTask.get()
将返回
该
任
务
的
结
果。例如,如果提交的是
对
象
Callable1
,
FutureTask.get()
方法
将返回
null
;如果提交的是
对
象
Callable2
,
FutureTask.get()
方法将返回
result
对
象。
下篇将详解
ThreadPoolExecutor