J.U.C之Executor框架入門指引
阿新 • • 發佈:2020-09-22
##### 1、Executor介面
> ```
> This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An {@code Executor} is normally used instead of explicitly creating threads.
> For example, rather than invoking {@code new Thread(new(RunnableTask())).start()} for each of a set of tasks
> ```
executor框架是jdk1.5時引入的一個介面,主要目的是解耦任務的建立和任務的執行,在jdk1.5之前,我們用執行緒建立一個任務時,通常是這樣 new Thread(new(RunnableTask())).start() ,當引入executor後我們這樣來建立執行任務:
```java
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
```
但由於executor介面只定義了方法void execute(Runnable command) 而沒有定義具體的實現,因而對於executor的不同實現,execute可能是建立一個新的執行緒並立即啟動,有可能是使用已有的工作執行緒執行,或者可能將任務放入等待佇列等待可用的工作執行緒。比如:
- 同步執行
```java
class DirectExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
}}
```
- 非同步執行
```java
class ThreadPerTaskExecutor implements Executor {
public void execute(Runnable r) {
new Thread(r).start();
}
}}
```
- 排隊執行
```java
class SerialExecutor implements Executor {
final Queue tasks = new ArrayDeque();
final Executor executor;
Runnable active;
SerialExecutor(Executor executor) {
this.executor = executor;
}
public synchronized void execute(final Runnable r) {
tasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((active = tasks.poll()) != null) {
executor.execute(active);
}
}
}}
```
##### 2、ExecutorService介面
除了繼承Executor介面的功能外,還提供了關閉執行器的方法,更加通用的submit方法(除了可以接收runnable介面任務還可以接收callable介面任務,**使用callable介面任務通常是需要獲取執行結果的任務,它通過返回的Future來獲取callable任務的執行結果**)和批量執行Callable介面任務。
##### 3、ScheduledExecutorService介面
除了繼承ExecutorService介面功能外,還提供了延時執行和間隔執行的功能(scheduleWithFixedDelay,scheduleAtFixedRate)
```java
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}}
```
##### 4、Executors 工廠
對於上述3個介面,jdk1.5 都提供了預設的實現,但是如果使用者自己去建立這些個預設實現的例項,就必須要了解這些預設例項的實現細節,而Executors 相當於就是一個簡單工廠,通過提供一些簡單的引數就可以創建出來我們想要的執行器。Executors為我們提供了五類執行器的建立:
- 建立固定執行緒數的Executor,返回ThreadPoolExecutor型別例項
```java
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory)
```
- 單個執行緒的Executor,返回FinalizableDelegatedExecutorService或DelegatedScheduledExecutorService型別例項
```java
public static ExecutorService newSingleThreadExecutor()
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory)
public static ScheduledExecutorService newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
```
- 可快取的Executor
```java
public static ExecutorService newCachedThreadPool()
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory)
```
- 延時、週期性的Executor
```java
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)
```
- fork/join Executor,返回ForkJoinPool類例項
```java
public static ExecutorService newWorkStealingPool(int parallelism)//並行級別
public static ExecutorService newWorkStealingPool(