最近使用了github上面的一个多线程下载的库 MultiThreadDownloader,发现挺好用。于是打开看了一下源码,发现了ExecutorService这个东西。之前多多少少接触到了这个东西,知道是java并发编程里面使用的,但是一直不是很了解所以花点时间看了一下。
下面这张图,就是ExecutorService的结构图
(ScheduledThreadPoolExecutor稍微复杂一点,后面会介绍到。)
Executors
class
这个类是一个工厂类,里面封装了很多构建`ExecutorService`实例的方法
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory)
所以`ExecutorService`实例的构建一般都是通过`Executors`来构建的。
举例:
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
ExecutorService executorService2 = Executors.newFixedThreadPool(10);
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
根据自己的需求创建不同的ExecutorService实例
Executor
interface
这个接口内部只有一个方法,也是这个结构中最核心的方法 `void execute(Runnable command)`
ExecutorService
interface
继承`Executor`所以自然是有 `execute`方法的
这个接口对Executor再一次进行了加强添加了一些管理方法
void shutdown();
<T> Future<T> submit();
<T> List<Future<T>> invokeAll(……)
throws InterruptedException;
<T> T invokeAny(……)
throws InterruptedException, ExecutionException;
这些方法具体的使用后面将会讲到
AbstractExecutorService
class ( abstract )
这个类是一个抽象类,规范了所有 工厂(Executors)构造的实例,也就是所有工厂构建的ExecutorService实例必须继承自AbstractExecutorService
看了上面的介绍大致可以看出ExecutorService外部的结构关系
那为什么要使用ExecutorService呢?
a. 每次new Thread新建对象性能差。
b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
c. 缺乏更多功能,如定时执行、定期执行、线程中断。
相比new Thread,Java提供的四种线程池的好处在于:
a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
c. 提供定时执行、定期执行、单线程、并发数控制等功能。
所以ExecutorService
提供了一种线程调度机制,使我们更加方便系统的管理 Thread