您好,登錄后才能下訂單哦!
這篇文章運用簡單易懂的例子給大家介紹一文讀懂java中的Executor、ExecutorService和ThreadPoolExecutor,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
java中Executor,ExecutorService,ThreadPoolExecutor詳解
1.Excutor
源碼非常簡單,只有一個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返回結果》
<T> Future<T> submit(Runnable task,T result)
提交一個 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:一旦正常或異常返回后,則取消尚未完成的任務
3.ThreadPoolExecutor
ThreadPoolExecutor是ExecutorService的一個實現類,它使用可能的幾個池線程之一執行每個提交的任務,通常使用 Executors 工廠方法配置。
線程池可以解決兩個不同問題:由于減少了每個任務調用的開銷,它們通常可以在執行大量異步任務時提供增強的性能,并且還可以提供綁定和管理資源(包括執行任務集時使用的線程)的方法。
每個 ThreadPoolExecutor 還維護著一些基本的統計數據,如完成的任務數。為了便于跨大量上下文使用,此類提供了很多可調整的參數和擴展鉤子 (hook)。
但是,強烈建議程序員使用較為方便的 Executors 工廠方法 Executors.newCachedThreadPool()(無界線程池,可以進行自動線程回收)、Executors.newFixedThreadPool(int)(固定大小線程池)和 Executors.newSingleThreadExecutor()(單個后臺線程),
它們均為大多數使用場景預定義了設置。否則,在手動配置和調整此類時,使用以下指導:
核心和最大池大小
ThreadPoolExecutor將根據corePoolSize(參見 getCorePoolSize())和 maximumPoolSize(參見 getMaximumPoolSize())
設置的邊界自動調整池大小。當新任務在方法 execute(java.lang.Runnable) 中提交時,如果運行的線程少于 corePoolSize, 則創建新線程來處理請求,即使有線程是空閑的。
如果運行的線程多于 corePoolSize 而少于 maximumPoolSize,則僅當隊列滿時才創建新線程。
如果設置的 corePoolSize 和 maximumPoolSize 相同,則創建了固定大小的線程池。
如果將 maximumPoolSize 設置為基本的無界值(如 Integer.MAX_VALUE),則允許池適應任意數量的并發任務。
在大多數情況下,核心和最大池大小僅基于構造來設置,不過也可以使用 setCorePoolSize(int) 和 setMaximumPoolSize(int) 進行動態更改。
注意1:在新任務被提交時,如果運行的core線程少于corePoolSize,才創建新core線程。并不是一開始就創建corePoolSize個core線程。
注意2:"如果運行的線程多于corePoolSize 而少于 maximumPoolSize,則僅當隊列滿時才創建新線程"
按需構造
核心線程最初只是在新任務到達時才被ThreadPoolExecutor創建和啟動的,
但是也可以手動調用方法 prestartCoreThread() 或 prestartAllCoreThreads()來的提前啟動核心線程。
如果構造帶有非空隊列的池,這時則可能希望預先啟動線程。
注意1:核心線程即core線程,只有當前線程數小于等于corePoolSize時,這時的線程才叫核心線程。
創建新線程
使用ThreadFactory創建新線程。如果沒有另外說明,則使用 Executors.defaultThreadFactory() 創建線程,他們在同一個ThreadGroup中
并且這些線程具有相同的 NORM_PRIORITY 優先級和非守護進程狀態。
通過提供不同的 ThreadFactory,可以改變線程的名稱、線程組、優先級、守護進程狀態,等等。
如果從 newThread 返回 null 時 ThreadFactory 未能創建線程,則執行程序將繼續運行,但不能執行任何任務。
注意1:可以指定創建線程的ThreadFactory,默認的是使用Executors.defaultThreadFactory()來創建線程,所有的線程都在一個ThreadGroup中。
保持活動時間
如果池中當前有多于corePoolSize 的線程,則這些多出的線程在空閑時間超過 keepAliveTime 時將會終止
(參見 getKeepAliveTime(java.util.concurrent.TimeUnit))。這提供了當池處于非活動狀態時減少資源消耗的方法。
如果池后來變得更為活動,則可以創建新的線程。也可以使用方法 setKeepAliveTime(long, java.util.concurrent.TimeUnit) 動態地更改此參數。
如果把值設為Long.MAX_VALUE TimeUnit.NANOSECONDS 的話,空閑線程不會被回收直到ThreadPoolExecutor為Terminate。
默認情況下,保持活動策略只在有多于corePoolSizeThreads 的線程時應用。
但是只要 keepAliveTime 值非 0,allowCoreThreadTimeOut(boolean) 方法也可將此超時策略應用于核心線程。
注意1:setKeepAliveTime(long, java.util.concurrent.TimeUnit)用于設置空閑線程最長的活動時間,
即如果空閑時間超過設定值,就停掉該線程,對該線程進行回收。
該策略默認只對非內核線程有用(即當前線程數大于corePoolSize),
可以調用allowCoreThreadTimeOut(boolean)方法將此超時策略擴大到核心線程
注意2:如果把值設為Long.MAX_VALUE TimeUnit.NANOSECONDS的話,空閑線程不會被回收直到ThreadPoolExecutor為Terminate。
排隊
所有 BlockingQueue 都可用于傳輸和保持提交的任務。可以使用此隊列與池大小進行交互:
* 如果運行的線程少于 corePoolSize,則 Executor 始終首選添加新的線程,而不進行排隊。
* 如果運行的線程等于或多于 corePoolSize,則 Executor 始終首選將請求加入隊列,而不添加新的線程。
* 如果無法將請求加入隊列,則創建新的線程,除非創建此線程超出 maximumPoolSize,在這種情況下,任務將被拒絕。
排隊有三種通用策略:
1. 直接提交。工作隊列的默認選項是 SynchronousQueue,它將任務直接提交給線程而不保持它們。
在此,如果不存在可用于立即運行任務的線程,則試圖把任務加入隊列將失敗,因此會構造一個新的線程。
此策略可以避免在處理可能具有內部依賴性的請求集時出現鎖。
直接提交通常要求無界maximumPoolSizes以避免拒絕新提交的任務。
當命令以超過隊列所能處理的平均數連續到達時,此策略允許線程無界的增長。
注意1:此策略允許線程無界的增長。
2. 無界隊列。使用無界隊列(例如,不具有預定義容量的 LinkedBlockingQueue)將導致在所有 corePoolSize 線程都忙時新任務在隊列中等待。
這樣,創建的線程就不會超過 corePoolSize。(因此,maximumPoolSize 的值也就無效了。)
當每個任務完全獨立于其他任務,即任務執行互不影響時,適合于使用無界隊列;例如,在 Web 頁服務器中。
這種排隊可用于處理瞬態突發請求,當命令以超過隊列所能處理的平均數連續到達時,此策略允許隊列無限的增長。
注意1:此策略允許隊列無限的增長。
3. 有界隊列。當使用有限的 maximumPoolSizes 時,有界隊列(如 ArrayBlockingQueue)有助于防止資源耗盡,但是可能較難調整和控制。
隊列大小和最大池大小可能需要相互折衷:使用大型隊列和小型池可以最大限度地降低 CPU 使用率、操作系統資源和上下文切換開銷,
但是可能導致人工降低吞吐量。如果任務頻繁阻塞(例如,如果它們是 I/O 邊界),則系統可能為超過您許可的更多線程安排時間。
使用小型隊列通常要求較大的池大小,CPU 使用率較高,但是可能遇到不可接受的調度開銷,這樣也會降低吞吐量。
被拒絕的任務
當 Executor 已經關閉,或Executor將有限邊界用于最大線程和工作隊列容量,且已經飽和時,
在方法 execute(java.lang.Runnable) 中提交的新任務將被拒絕。
在以上兩種情況下,execute 方法都將調用其
RejectedExecutionHandler的RejectedExecutionHandler.rejectedExecution(java.lang.Runnable,
java.util.concurrent.ThreadPoolExecutor) 方法。
下面提供了四種預定義的處理程序策略:
1. 在默認的 ThreadPoolExecutor.AbortPolicy 中,處理程序遭到拒絕將拋出運行時RejectedExecutionException。
2. 在 ThreadPoolExecutor.CallerRunsPolicy中,線程調用運行該任務的 execute 本身。
此策略提供簡單的反饋控制機制,能夠減緩新任務的提交速度。
3. 在ThreadPoolExecutor.DiscardPolicy中,不能執行的任務將被刪除。
4. 在ThreadPoolExecutor.DiscardOldestPolicy 中,如果執行程序尚未關閉,
則位于工作隊列頭部的任務將被刪除,然后重試執行程序(如果再次失敗,則重復此過程)。
定義和使用其他種類的RejectedExecutionHandler類也是可能的,但這樣做需要非常小心,尤其是當策略僅用于特定容量或排隊策略時
注意1:AbortPolicy,CallerRunsPolicy,DiscardPolicy和DiscardOldestPolicy都是rejectedExecution的一種實現。
當然也可以自己定義個rejectedExecution實現。
鉤子 (hook) 方法
此類提供 protected 可重寫的 beforeExecute(java.lang.Thread, java.lang.Runnable)
和 afterExecute(java.lang.Runnable, java.lang.Throwable) 方法,這兩種方法分別在執行每個任務之前和之后調用。
它們可用于操縱執行環境;例如,重新初始化 ThreadLocal、搜集統計信息或添加日志條目。
此外,還可以重寫方法 terminated() 來執行 Executor 完全終止后需要完成的所有特殊處理。
如果鉤子 (hook) 或回調方法拋出異常,則ThreadPoolExecutor的所有線程將依次失敗并突然終止。
隊列維護
方法 getQueue() 允許出于監控和調試目的而訪問工作隊列。強烈反對出于其他任何目的而使用此方法。
remove(java.lang.Runnable) 和 purge() 這兩種方法可用于在取消大量已排隊任務時幫助進行存儲回收。
注意1:如果任務取消,ThreadPoolExecutor應該自己是可以進行存儲回收的。
取消的任務不會再次執行,但是它們可能在工作隊列中累積,直到worker線程主動將其移除
外部使用remove(java.lang.Runnable)和purge()可以把它們立即從隊列中移除。
終止
如果ThreadPoolExecutor在程序中沒有任何引用且沒有任何活動線程,它也不會自動 shutdown。
如果希望確保回收線程(即使用戶忘記調用 shutdown()),則必須安排未使用的線程最終終止:
設置適當保持活動時間,使用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(); } } }}
關于它的使用請參考《ExecutorService》
Nested Classes | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
ThreadPoolExecutor.AbortPolicy | A handler for rejected tasks that throws a RejectedExecutionException. | ||||||||||
ThreadPoolExecutor.CallerRunsPolicy | A handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method, unless the executor has been shut down, in which case the task is discarded. | ||||||||||
ThreadPoolExecutor.DiscardOldestPolicy | A handler for rejected tasks that discards the oldest unhandled request and then retries execute, unless the executor is shut down, in which case the task is discarded. | ||||||||||
ThreadPoolExecutor.DiscardPolicy | A handler for rejected tasks that silently discards the rejected task. |
主要構造函數:
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。
主要成員函數
public void 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系列接口
Submits a Runnable task for execution and returns a Future representing that task. 如果執行成功就返回T result | |
Submits a value-returning task for execution and returns a Future representing the pending results of the task. | |
Submits a Runnable task for execution and returns a Future representing that task. |
關于一文讀懂java中的Executor、ExecutorService和ThreadPoolExecutor就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。