一個Executor
蝎土,提供管理終止的方法和可以生成Future
以跟蹤一個或多個異步任務(wù)進(jìn)度的方法。
可以關(guān)閉ExecutorService
邢笙,這將導(dǎo)致它拒絕新任務(wù)芋齿。
提供了兩種不同的方法來關(guān)閉ExecutorService
:
-
shutdown
方法將允許先前提交的任務(wù)在終止之前執(zhí)行 -
shutdownNow
方法阻止等待任務(wù)啟動并嘗試停止當(dāng)前正在執(zhí)行的任務(wù)腥寇。終止時,執(zhí)行程序沒有正在執(zhí)行的任務(wù)沟突,沒有等待執(zhí)行的任務(wù)花颗,也沒有任何新任務(wù)可以提交。 應(yīng)關(guān)閉未使用的ExecutorService
以允許回收其資源惠拭。
方法submit
通過創(chuàng)建并返回可用于取消執(zhí)行和/或等待完成的Future
來擴(kuò)展基本方法Executor excute(Runnable)
扩劝。 方法invokeAny
和invokeAll
執(zhí)行最常用的批量執(zhí)行形式,執(zhí)行一組任務(wù)职辅,然后等待至少一個或全部完成棒呛。 (類ExecutorCompletionService
可用于編寫這些方法的自定義變體。)
Executors
類為此包中提供的執(zhí)行程序服務(wù)提供工廠方法域携。
下面是網(wǎng)絡(luò)服務(wù)的草圖簇秒,其中線程池中的線程為傳入請求提供服務(wù)。 它使用預(yù)配置的Executors#newFixedThreadPool
工廠方法:
class NetworkService implements Runnable {
private final ServerSocket serverSocket;
private final ExecutorService pool;
public NetworkService(int port, int poolSize)
throws IOException {
serverSocket = new ServerSocket(port);
pool = Executors.newFixedThreadPool(poolSize);
}
public void run() { // run the service
try {
for (;;) {
pool.execute(new Handler(serverSocket.accept()));
}
} catch (IOException ex) {
pool.shutdown();
}
}
}
class Handler implements Runnable {
private final Socket socket;
Handler(Socket socket) {
this.socket = socket;
}
public void run() {
// read and service request on socket
}
}
以下方法分兩個階段關(guān)閉ExecutorService
秀鞭,首先調(diào)用shutdown
拒絕傳入的任務(wù)趋观,然后在必要時調(diào)用shutdownNow
以取消任何延遲的任務(wù):
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
Callable<V>
返回結(jié)果并可能拋出異常的任務(wù)。 實(shí)現(xiàn)者定義一個沒有名為call
的參數(shù)的方法锋边。
Callable
接口類似于java.lang.Runnable
皱坛,因?yàn)樗鼈兌际菫槠鋵?shí)例可能由另一個線程執(zhí)行的類而設(shè)計(jì)的。 但是豆巨,Runnable
不返回結(jié)果剩辟,也不能拋出已檢查的異常。
Executors
類包含將其他常用表單轉(zhuǎn)換為Callable
類的實(shí)用程序方法往扔。
V call() throws Exception;
計(jì)算結(jié)果贩猎,或者如果無法執(zhí)行則拋出異常。
Future<V>
Future
表示異步計(jì)算的結(jié)果萍膛。 提供方法以檢查計(jì)算是否完成吭服,等待其完成,以及檢索計(jì)算結(jié)果蝗罗。 只有在計(jì)算完成后才能使用方法get
檢索結(jié)果艇棕,必要時阻塞直到準(zhǔn)備就緒麦到。 取消由cancel
方法執(zhí)行。 提供了其他方法來確定任務(wù)是否正常完成或被取消欠肾。 計(jì)算完成后,無法取消計(jì)算拟赊。 如果您想使用Future
以取消可取性但不提供可用的結(jié)果刺桃,您可以聲明Future <?>
形式的類型并返回null
作為結(jié)果基本任務(wù)吸祟。
interface ArchiveSearcher { String search(String target); }
class App {
ExecutorService executor = ...
ArchiveSearcher searcher = ...
void showSearch(final String target) throws InterruptedException {
Future<String> future
= executor.submit(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
displayOtherThings(); // do other things while searching
try {
displayText(future.get()); // use future
} catch (ExecutionException ex) { cleanup(); return; }
}
}
FutureTask
類是實(shí)現(xiàn)Runnable
的Future
的實(shí)現(xiàn)瑟慈,因此可以由Executor
執(zhí)行。 例如屋匕,submit
的上述結(jié)構(gòu)可以替換為:
FutureTask<String> future =
new FutureTask<>(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
executor.execute(future);