源碼非常簡單,只有一個execute(Runnable command)回調接口
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the <tt>Executor</tt> implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution.
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
執行已提交的 Runnable
任務對象。此接口提供一種將任務提交與每個任務將如何運行的機制(包括線程使用的細節、調度等)分離開來的方法。通常使用 Executor 而不是顯式地創建線程。例如,可能會使用以下方法,而不是為一組任務中的每個任務調用 new Thread(new(RunnableTask())).start():
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
...
不過,Executor 接口並沒有嚴格地要求執行是異步的。在最簡單的情況下,執行程序可以在調用方的線程中立即運行已提交的任務:
class DirectExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
}
更常見的是,任務是在某個不是調用方線程的線程中執行的。以下執行程序將為每個任務生成一個新線程。
class ThreadPerTaskExecutor implements Executor {
public void execute(Runnable r) {
new Thread(r).start();
}
}
許多 Executor 實現都對調度任務的方式和時間強加了某種限制。以下執行程序使任務提交與第二個執行程序保持連續,這說明了一個復合執行程序。
class SerialExecutor implements Executor {
final Queue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();
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.ExcutorService接口
ExecutorService提供了管理終止的方法,以及可為跟蹤一個或多個異步任務執行狀況而生成 Future 的方法。 可以關閉 ExecutorService,這將導致其拒絕新任務。提供兩個方法來關閉 ExecutorService。 shutdown()方法在終止前允許執行以前提交的任務,而 shutdownNow() 方法阻止等待任務的啟動並試圖停止當前正在執行的任務。在終止后,執行程序沒有任務在執行,也沒有任務在等待執行,並且無法提交新任務。應該關閉未使用的 ExecutorService以允許回收其資源。 通過創建並返回一個可用於取消執行和/或等待完成的 Future,方法submit擴展了基本方法 Executor.execute(java.lang.Runnable)。 方法 invokeAny 和 invokeAll 是批量執行的最常用形式,它們執行任務 collection,然后等待至少一個, 或全部任務完成(可使用 ExecutorCompletionService類來編寫這些方法的自定義變體)。 Executors類為創建ExecutorService提供了便捷的工廠方法。 注意1:它只有一個直接實現類ThreadPoolExecutor和間接實現類ScheduledThreadPoolExecutor。 關於ThreadPoolExecutor的更多內容請參考《ThreadPoolExecutor》 關於ScheduledThreadPoolExecutor的更多內容請參考《ScheduledThreadPoolExecutor》 用法示例 下面給出了一個網絡服務的簡單結構,這里線程池中的線程作為傳入的請求。它使用了預先配置的 Executors.newFixedThreadPool(int) 工廠方法:
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 } }
下列方法分兩個階段關閉 ExecutorService。第一階段調用 shutdown 拒絕傳入任務,然后等60秒后,任務還沒執行完成,就調用 shutdownNow(如有必要)取消所有遺留的任務:
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(); } }
內存一致性效果:線程中向 ExecutorService 提交 Runnable 或 Callable 任務之前的操作 happen-before 由該任務所提取的所有操作,后者依次 happen-before 通過 Future.get() 獲取的結果。
主要函數:
void shutdown()
啟動一個關閉命令,不再接受新任務,當所有已提交任務執行完后,就關閉。如果已經關閉,則調用沒有其他作用。
拋出:
SecurityException - 如果安全管理器存在並且關閉,此 ExecutorService 可能操作某些不允許調用者修改的線程(因為它沒有保持 RuntimePermission("modifyThread")),或者安全管理器的 checkAccess 方法拒絕訪問。
List<Runnable> shutdownNow()
試圖停止所有正在執行的活動任務,暫停處理正在等待的任務,並返回等待執行的任務列表。
無法保證能夠停止正在處理的活動執行任務,但是會盡力嘗試。例如,通過 Thread.interrupt() 來取消典型的實現,所以任何任務無法響應中斷都可能永遠無法終止。
返回:
從未開始執行的任務的列表
拋出:
SecurityException - 如果安全管理器存在並且關閉,
此 ExecutorService 可能操作某些不允許調用者修改的線程(因為它沒有保持 RuntimePermission("modifyThread")),
或者安全管理器的 checkAccess 方法拒絕訪問。
注意1: 它會返回等待執行的任務列表。
注意2: 無法保證能夠停止正在處理的活動執行任務,但是會盡力嘗試。例如,通過 Thread.interrupt() 來取消,
所以任何任務無法響應中斷都可能永遠無法終止。
boolean isShutdown()
如果此執行程序已關閉,則返回 true。
返回:
如果此執行程序已關閉,則返回 true
boolean isTerminated()
如果關閉后所有任務都已完成,則返回 true。注意,除非首先調用 shutdown 或 shutdownNow,否則 isTerminated 永不為 true。
返回:
如果關閉后所有任務都已完成,則返回 true
boolean awaitTermination(long timeout,TimeUnit unit) throws InterruptedException
等待(阻塞)直到關閉或最長等待時間或發生中斷
參數:
timeout - 最長等待時間
unit - timeout 參數的時間單位
返回:
如果此執行程序終止,則返回 true;如果終止前超時期滿,則返回 false
拋出:
InterruptedException - 如果等待時發生中斷
注意1:如果此執行程序終止(關閉),則返回 true;如果終止前超時期滿,則返回 false
<T> Future<T> submit(Callable<T> task)
提交一個返回值的任務用於執行,返回一個表示任務的未決結果的 Future。該 Future 的 get 方法在成功完成時將會返回該任務的結果。
如果想立即阻塞任務的等待,則可以使用 result = exec.submit(aCallable).get(); 形式的構造。
注:Executors 類包括了一組方法,可以轉換某些其他常見的類似於閉包的對象,
例如,將 PrivilegedAction 轉換為 Callable 形式,這樣就可以提交它們了。
參數:
task - 要提交的任務
返回:
表示任務等待完成的 Future
拋出:
RejectedExecutionException - 如果任務無法安排執行
NullPointerException - 如果該任務為 null
注意:關於submit的使用和Callable可以參閱《使用Callable返回結果》
提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。該 Future 的 get 方法在成功完成時將會返回給定的結果。
參數:
task - 要提交的任務
result - 返回的結果
返回:
表示任務等待完成的 Future
拋出:
RejectedExecutionException - 如果任務無法安排執行
NullPointerException - 如果該任務為 null
注意:關於submit的使用可以參閱《Callable》
Future<?> submit(Runnable task)
提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。該 Future 的 get 方法在成功 完成時將會返回 null。
參數:
task - 要提交的任務
返回:
表示任務等待完成的 Future
拋出:
RejectedExecutionException - 如果任務無法安排執行
NullPointerException - 如果該任務為 null
注意:關於submit的使用可以參閱《使用Callable返回結果》
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException
執行給定的任務,當所有任務完成時,返回保持任務狀態和結果的 Future 列表。返回列表的所有元素的 Future.isDone() 為 true。
注意,可以正常地或通過拋出異常來終止已完成 任務。如果正在進行此操作時修改了給定的 collection,則此方法的結果是不確定的。
參數:
tasks - 任務 collection
返回:
表示任務的 Future 列表,列表順序與給定任務列表的迭代器所生成的順序相同,每個任務都已完成。
拋出:
InterruptedException - 如果等待時發生中斷,在這種情況下取消尚未完成的任務。
NullPointerException - 如果任務或其任意元素為 null
RejectedExecutionException - 如果所有任務都無法安排執行
注意1:該方法會一直阻塞直到所有任務完成。
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout,
TimeUnit unit)
throws InterruptedException
執行給定的任務,當所有任務完成或超時期滿時(無論哪個首先發生),返回保持任務狀態和結果的 Future 列表。返回列表的所有元素的 Future.isDone() 為 true。一旦返回后,即取消尚未完成的任務。注意,可以正常地或通過拋出異常來終止已完成 任務。如果此操作正在進行時修改了給定的 collection,則此方法的結果是不確定的。
參數:
tasks - 任務 collection
timeout - 最長等待時間
unit - timeout 參數的時間單位
返回:
表示任務的 Future 列表,列表順序與給定任務列表的迭代器所生成的順序相同。
如果操作未超時,則已完成所有任務。如果確實超時了,則某些任務尚未完成。
拋出:
InterruptedException - 如果等待時發生中斷,在這種情況下取消尚未完成的任務
NullPointerException - 如果任務或其任意元素或 unit 為 null
RejectedExecutionException - 如果所有任務都無法安排執行
注意1:該方法會一直阻塞直到所有任務完成或超時。
注意2:如果確實超時了,則某些任務尚未完成。【那么這些尚未完成的任務應該被系統取消】。
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException,
ExecutionException
執行給定的任務,如果某個任務已成功完成(也就是未拋出異常),則返回其結果。一旦正常或異常返回后,則取消尚未完成的任務。
如果此操作正在進行時修改了給定的 collection,則此方法的結果是不確定的。
參數:
tasks - 任務 collection
返回:
某個任務返回的結果
拋出:
InterruptedException - 如果等待時發生中斷
NullPointerException - 如果任務或其任意元素為 null
IllegalArgumentException - 如果任務為空
ExecutionException - 如果沒有任務成功完成
RejectedExecutionException - 如果任務無法安排執行
注意1:該方法會一直阻塞直到有一個任務完成。
注意2:一旦正常或異常返回后,則取消尚未完成的任務
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout,
TimeUnit unit)
throws InterruptedException,
ExecutionException,
TimeoutException
執行給定的任務,如果在給定的超時期滿前某個任務已成功完成(也就是未拋出異常),則返回其結果。一旦正常或異常返回后,則取消尚未完成的任務。如果此操作正在進行時修改了給定的 collection,則此方法的結果是不確定的。
參數:
tasks - 任務 collection
timeout - 最長等待時間
unit - timeout 參數的時間單位
返回:
某個任務返回的結果
拋出:
InterruptedException - 如果等待時發生中斷
NullPointerException - 如果任務或其任意元素或 unit 為 null
TimeoutException - 如果在所有任務成功完成之前給定的超時期滿
ExecutionException - 如果沒有任務成功完成
RejectedExecutionException - 如果任務無法安排執行
注意1:該方法會一直阻塞直到有一個任務完成。
注意2:一旦正常或異常返回后,則取消尚未完成的任務
每個 還維護着一些基本的統計數據,如完成的任務數。為了便於跨大量上下文使用,此類提供了很多可調整的參數和擴展鈎子 (hook)。
但是,強烈建議程序員使用較為方便的 Executors 工廠方法 (無界線程池,可以進行自動線程回收)、(固定大小線程池)和(單個后台線程),
它們均為大多數使用場景預定義了設置。否則,在手動配置和調整此類時,使用以下指導:
核心和最大池大小ThreadPoolExecutorcorePoolSize maximumPoolSize當新任務在方法中提交時,如果運行的線程少於 , 則創建新線程來處理請求,即使有線程是空閑的。
corePoolSize maximumPoolSizcorePoolSizemaximumPoolSizemaximumPoolSize Integer.MAX_VALUEsetCorePoolSize(int) setMaximumPoolSize(int)
按需構造 prestartCoreThread()prestartAllCoreThreads()
使用創建新線程。如果沒有另外說明,則使用 創建線程,他們在同一個ThreadGroup中
並且這些線程具有相同的 NORM_PRIORITY 優先級和非守護進程狀態。
通過提供不同的 ThreadFactory,可以改變線程的名稱、線程組、優先級、守護進程狀態,等等。
如果從 newThread 返回 null 時 ThreadFactory 未能創建線程,則執行程序將繼續運行,但不能執行任何任務。
注意1:可以指定創建線程的ThreadFactory,默認的是使用Executors.defaultThreadFactory()來創建線程,所有的線程都在一個ThreadGroup中。
保持活動時間 如果池中當前有多於corePoolSize 的線程,則這些多出的線程在空閑時間超過 keepAliveTime 時將會終止
(參見 )。這提供了當池處於非活動狀態時減少資源消耗的方法。
如果池后來變得更為活動,則可以創建新的線程。也可以使用方法 setKeepAliveTime(long, java.util.concurrent.TimeUnit) 動態地更改此參數。
如果把值設為 的話,空閑線程不會被回收直到ThreadPoolExecutor為Terminate。
默認情況下,保持活動策略只在有多於corePoolSizeThreads 的線程時應用。
但是只要 keepAliveTime 值非 0,方法也可將此超時策略應用於核心線程。
注意1:setKeepAliveTime(long, java.util.concurrent.TimeUnit)用於設置空閑線程最長的活動時間,
即如果空閑時間超過設定值,就停掉該線程,對該線程進行回收。
該策略默認只對非內核線程有用(即當前線程數大於corePoolSize),
可以調用allowCoreThreadTimeOut(boolean)方法將此超時策略擴大到核心線程
注意2:如果把值設為Long.MAX_VALUE TimeUnit.NANOSECONDS的話,空閑線程不會被回收直到ThreadPoolExecutor為Terminate。
排隊BlockingQueue。
排隊有三種通用策略:
:此策略允許線程無界的增長。
3. 有界隊列。當使用有限的 maximumPoolSizes 時,有界隊列(如 ArrayBlockingQueue)有助於防止資源耗盡,但是可能較難調整和控制。
隊列大小和最大池大小可能需要相互折衷:使用大型隊列和小型池可以最大限度地降低 CPU 使用率、操作系統資源和上下文切換開銷,
但是可能導致人工降低吞吐量。如果任務頻繁阻塞(例如,如果它們是 I/O 邊界),則系統可能為超過您許可的更多線程安排時間。
使用小型隊列通常要求較大的池大小,CPU 使用率較高,但是可能遇到不可接受的調度開銷,這樣也會降低吞吐量。
被拒絕的任務RejectedExecutionHandlerRejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) ThreadPoolExecutor.AbortPolicy ThreadPoolExecutor.CallerRunsPolicyThreadPoolExecutor.DiscardPolicyThreadPoolExecutor.DiscardOldestPolicy java.lang.Thread, java.lang.Runnable)
和 (java.lang.Runnable, java.lang.Throwable) 方法,這兩種方法分別在執行每個任務之前和之后調用。
它們可用於操縱執行環境;例如,重新初始化 ThreadLocal、搜集統計信息或添加日志條目。
此外,還可以重寫方法 來執行 Executor 完全終止后需要完成的所有特殊處理。
removepurge() removepurge()
設置適當保持活動時間,使用0核心線程的下邊界和/或設置 allowCoreThreadTimeOut(boolean)。
擴展示例。此類的大多數擴展可以重寫一個或多個受保護的鈎子 (hook) 方法。例如,下面是一個添加了簡單的暫停/恢復功能的子類:
class PausableThreadPoolExecutor extends ThreadPoolExecutor { private boolean isPaused; private ReentrantLock pauseLock = new ReentrantLock(); private Condition unpaused = pauseLock.newCondition(); public PausableThreadPoolExecutor(...) { super(...);
protected void beforeExecute(Thread t, Runnable r) { super.beforeExecute(t, r); pauseLock.lock(); try { while (isPaused) unpaused.await(); } catch (InterruptedException ie) { t.interrupt(); } finally { pauseLock.unlock(); } } public void pause() { pauseLock.lock(); try { isPaused = true; } finally { pauseLock.unlock(); } } public void resume() { pauseLock.lock(); try { isPaused = false; unpaused.signalAll(); } finally { pauseLock.unlock(); } } }}
關於它的使用請參考《ExecutorServiceclass
ThreadPoolExecutor.AbortPolicy | RejectedExecutionException. | ||||||||||||
ThreadPoolExecutor.CallerRunsPolicy | execute method, unless the executor has been shut down, in which case the task is discarded. | ||||||||||||
ThreadPoolExecutor.DiscardOldestPolicy | execute, unless the executor is shut down, in which case the task is discarded. | ||||||||||||
ThreadPoolExecutor.DiscardPolicy | public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) 用給定的初始參數和默認的線程工廠及被拒絕的執行處理程序創建新的 ThreadPoolExecutor。 使用 Executors 工廠方法之一比使用此通用構造方法方便得多。 參數: corePoolSize - 池中所保存的線程數,包括空閑線程。 maximumPoolSize - 池中允許的最大線程數。 keepAliveTime - 當線程數大於核心時,此為終止前多余的空閑線程等待新任務的最長時間。 unit - keepAliveTime 參數的時間單位。 workQueue - 執行前用於保持任務的隊列。此隊列僅保持由 execute 方法提交的 Runnable 任務。 拋出: IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小於 0,或者 maximumPoolSize 小於等於 0, 或者 corePoolSize 大於 maximumPoolSize。 NullPointerException - 如果 workQueue 為 null public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) 用給定的初始參數和默認被拒絕的執行處理程序創建新的 ThreadPoolExecutor。 參數: corePoolSize - 池中所保存的線程數,包括空閑線程。 maximumPoolSize - 池中允許的最大線程數。 keepAliveTime - 當線程數大於核心時,此為終止前多余的空閑線程等待新任務的最長時間。 unit - keepAliveTime 參數的時間單位。 workQueue - 執行前用於保持任務的隊列。此隊列僅保持由 execute 方法提交的 Runnable 任務。 threadFactory - 執行程序創建新線程時使用的工廠。 拋出: IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小於 0,或者 maximumPoolSize 小於等於 0,或者 corePoolSize 大於 maximumPoolSize。 NullPointerException - 如果 workQueue 或 threadFactory 為 null。 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) 用給定的初始參數和默認的線程工廠創建新的 ThreadPoolExecutor。 參數: corePoolSize - 池中所保存的線程數,包括空閑線程。 maximumPoolSize - 池中允許的最大線程數。 keepAliveTime - 當線程數大於核心時,此為終止前多余的空閑線程等待新任務的最長時間。 unit - keepAliveTime 參數的時間單位。 workQueue - 執行前用於保持任務的隊列。此隊列僅由保持 execute 方法提交的 Runnable 任務。 handler - 由於超出線程范圍和隊列容量而使執行被阻塞時所使用的處理程序。 拋出: IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小於 0,或者 maximumPoolSize 小於等於 0, 或者 corePoolSize 大於 maximumPoolSize。
execute(Runnable command)
在將來某個時間執行給定任務。可以在新線程中或者在現有池線程中執行該任務。 如果無法將任務提交執行,或者因為此執行程序已關閉,或者因為已達到其容量,則該任務由當前 RejectedExecutionHandler 處理。 參數: command - 要執行的任務。 拋出: RejectedExecutionException - 如果無法接收要執行的任務,則由 RejectedExecutionHandler 決定是否拋出 RejectedExecutionException NullPointerException - 如果命令為 null public void shutdown() 按過去執行已提交任務的順序發起一個有序的關閉,但是不接受新任務。如果已經關閉,則調用沒有其他作用。 拋出: SecurityException - 如果安全管理器存在並且關閉此 ExecutorService 可能操作某些不允許調用者修改的線程(因為它沒有 RuntimePermission("modifyThread")),或者安全管理器的 checkAccess 方法拒絕訪問。 public List<Runnable> shutdownNow() 嘗試停止所有的活動執行任務、暫停等待任務的處理,並返回等待執行的任務列表。在從此方法返回的任務隊列中排空(移除)這些任務。 並不保證能夠停止正在處理的活動執行任務,但是會盡力嘗試。 此實現通過 Thread.interrupt() 取消任務,所以無法響應中斷的任何任務可能永遠無法終止。 返回: 從未開始執行的任務的列表。 拋出: SecurityException - 如果安全管理器存在並且關閉此 ExecutorService 可能操作某些不允許調用者修改的線程(因為它沒有 RuntimePermission("modifyThread")), 或者安全管理器的 checkAccess 方法拒絕訪問。 public int prestartAllCoreThreads() 啟動所有核心線程,使其處於等待工作的空閑狀態。僅當執行新任務時,此操作才重寫默認的啟動核心線程策略。 返回: 已啟動的線程數 public boolean allowsCoreThreadTimeOut() 如果此池允許核心線程超時和終止,如果在 keepAlive 時間內沒有任務到達,新任務到達時正在替換(如果需要),則返回 true。當返回 true 時,適用於非核心線程的相同的保持活動策略也同樣適用於核心線程。當返回 false(默認值)時,由於沒有傳入任務,核心線程不會終止。 返回: 如果允許核心線程超時,則返回 true;否則返回 false public void allowCoreThreadTimeOut(boolean value) 如果在保持活動時間內沒有任務到達,新任務到達時正在替換(如果需要),則設置控制核心線程是超時還是終止的策略。當為 false(默認值)時,由於沒有傳入任務,核心線程將永遠不會中止。當為 true 時,適用於非核心線程的相同的保持活動策略也同樣適用於核心線程。為了避免連續線程替換,保持活動時間在設置為 true 時必須大於 0。通常應該在主動使用該池前調用此方法。 參數: value - 如果應該超時,則為 true;否則為 false 拋出: IllegalArgumentException - 如果 value 為 true 並且當前保持活動時間不大於 0。 public boolean remove(Runnable task) 從執行程序的內部隊列中移除此任務(如果存在),從而如果尚未開始,則讓其不再運行。 此方法可用作取消方案的一部分。它可能無法移除在放置到內部隊列之前已經轉換為其他形式的任務。 例如,使用 submit 輸入的任務可能被轉換為維護 Future 狀態的形式。但是,在此情況下,purge() 方法可用於移除那些已被取消的 Future。 參數: task - 要移除的任務 返回: 如果已經移除任務,則返回 true public void purge() 嘗試從工作隊列移除所有已取消的 Future 任務。此方法可用作存儲回收操作,它對功能沒有任何影響。 取消的任務不會再次執行,但是它們可能在工作隊列中累積,直到worker線程主動將其移除。 調用此方法將試圖立即移除它們。但是,如果出現其他線程的干預,那么此方法移除任務將失敗。
當然它還實現了的ExecutorService的submit系列接口
abstract <T> Future<T>
|