[TOC]
声明
该系列文章只是记录本人回顾java多线程编程时候记录的笔记。文中所用语言并非严谨的专业术语(太严谨的术语其实本人也不会……)。难免有理解偏差的地方,欢迎指正。
另外,大神请绕路。不喜勿喷。
毕竟好记性不如烂笔头嘛,而且许多东西只要不是你经常用的最终都会一丢丢一丢丢地给忘记。
1 Excutor家族概览
上一篇 http://blog.csdn.net/hylexus/article/details/53456463 中介绍了java线程池的相关概念和基本用法。
然而在平时真正使用的时候往往不是自己手动创建线程池的。而是通过本节要介绍的Excutor
和ExcutorService
来使用的。
以下是Excutor家族的主要成员
2 成员介绍
2.1 Executors
Executors是一个专门为Executor
、ExecutorService
、ScheduledExecutorService
、ThreadFactory
、Callable
等设计的工厂类。
2.2 ThreadPoolExecutor
ThreadPoolExecutor就是 上一篇文章 介绍的线程池。他是整个线程池的核心组件。
然而,在多数情况下,ThreadPoolExecutor的实例的创建并不是我们自己new
的。
而是通过java.util.concurrent.Executors
这个工厂类来创建的。Executors
提供方法以快捷的创建三种常用的 ThreadPoolExecutor
:
- 固定大小的线程池
public static ExecutorService newFixedThreadPool(int nThreads){}
public static ExecutorService newFixedThreadPool(
int nThreads, ThreadFactory threadFactory){
}
- 单个线程的线程池
public static ExecutorService newSingleThreadExecutor(){}
public static ExecutorService newSingleThreadExecutor(
ThreadFactory threadFactory){
}
- 按需创建新线程的线程池
maximumPoolSize为Integer.MAX_VALUE
,队列类型为 SynchronousQueue
.
public static ExecutorService newCachedThreadPool(){}
public static ExecutorService newCachedThreadPool(
ThreadFactory threadFactory){
}
2.3 ScheduledThreadPoolExecutor
简单理解就是可调度
版的ThreadPoolExecutor。一般是用来执行周期性的可调度的任务的。
Executors
提供方法以快捷的创建 ScheduledThreadPoolExecutor
:
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize){}
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
}
2.4 Runnable、Callable
这两个接口表示可以被ScheduledThreadPoolExecutor
或ThreadPoolExecutor
执行的任务的抽象。
在Excutors
工厂中提供了将Runnable
包装为Callable
的方法:
public static Callable<Object> callable(Runnable task){}
public static <T> Callable<T> callable(Runnable task, T result) {}
2.5 Future、FutureTask
Future表示异步执行的任务的返回结果。FutureTask是Future接口的间接实现类。
其实FutureTask不仅实现了Future接口,同时还实现了Runnable接口。
FutureTask的状态:
- 未启动:刚刚被创建,尚未调动run()方法的状态
- 已启动:调用了run()方法
- 已完成:run方法执行完毕
FutureTask类的常用方法:
- get() : Waits if necessary for the computation to complete, and then retrieves its result.
- 在未启动状态调用get()==>阻塞
- 在已启动状态调用get()==>阻塞
- 在已完成状态调用get()==>返回执行结果,或者抛出异常
- cancel():取消执行
- 在未启动状态调用cancel(),将导致该任务永远不会被执行。
- 在已启动状态调用cancel(),将会使用中断该任务线程的方式来尝试取消任务的执行。
- 在调用时如果该任务已经被终止、或已经完成或者由于一些原因无法终止该方法都将返回false.
2.6 Executor、ExecutorService
java.util.concurrent.Executor
是一个可以执行提交给他的任务的对象的抽象接口。只包含一个方法:
void execute(Runnable command);
java.util.concurrent.ExecutorService
是Executor
的子接口,提供了更加丰富的接口方法。
3 简单示例
ExecutorService service = Executors.newFixedThreadPool(12);
Future<List<String>> future = service.submit(new Callable<List<String>>() {
@Override
public List<String> call() throws Exception {
// 模拟查询耗时3秒
Thread.sleep(3000);
return Arrays.asList("tom", "cat", "apache", "Spark", "Scala");
}
});
try {
List<String> list = future.get();
list.forEach(System.out::println);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
service.shutdown();
}
参考资料
- 《java并发编程的艺术》