ThreadPoolExecutor 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
, ExecutorService
會使用數個可能數個集區線程之一來執行每個送出的工作,通常是使用 Executors
Factory 方法設定的。
[Android.Runtime.Register("java/util/concurrent/ThreadPoolExecutor", DoNotGenerateAcw=true)]
public class ThreadPoolExecutor : Java.Util.Concurrent.AbstractExecutorService
[<Android.Runtime.Register("java/util/concurrent/ThreadPoolExecutor", DoNotGenerateAcw=true)>]
type ThreadPoolExecutor = class
inherit AbstractExecutorService
- 繼承
- 衍生
- 屬性
備註
, ExecutorService
會使用數個可能數個集區線程之一來執行每個送出的工作,通常是使用 Executors
Factory 方法設定的。
線程集區解決了兩個不同的問題:它們通常會在執行大量異步工作時提供改善的效能,因為每個工作調用額外負荷降低,而且它們提供系結和管理資源的方法,包括執行工作集合時所耗用的線程。 每個專案 ThreadPoolExecutor
也會維護一些基本統計數據,例如已完成的工作數目。
為了在各種不同的內容中很有用,這個類別提供許多可調整的參數和擴充性勾點。 不過,敦促程式設計人員使用更方便 Executors
的處理站方法 Executors#newCachedThreadPool
(未系結的線程集區,具有自動線程回收)、 Executors#newFixedThreadPool
(固定大小線程集區)和 Executors#newSingleThreadExecutor
(單一背景線程),以預先設定最常見使用案例的設定。 否則,在手動設定及調整此類別時,請使用下列指南:
<dl>
<dt>Core 和最大集區大小</dt>
<dd>A ThreadPoolExecutor
會根據 corePoolSize 所設定的界限自動調整集區大小(#getPoolSize
請參閱#getCorePoolSize
)和 maximumPoolSize (請參閱 )。#getMaximumPoolSize
在方法 #execute(Runnable)
中提交新工作時,如果執行的核心PoolSize 線程少於 ,則會建立新的線程來處理要求,即使其他背景工作線程處於閑置狀態也一樣。 否則,如果執行的線程少於 maximumPoolSize 線程,則只有在佇列已滿時,才會建立新的線程來處理要求。 藉由設定 corePoolSize 和 maximumPoolSize 相同,您可以建立固定大小的線程集區。 將 maximumPoolSize 設定為基本上未系結的值,例如 Integer.MAX_VALUE
,您可以允許集區容納任意數目的並行工作。 大部分情況下,核心和最大集區大小只會在建構時設定,但也可能使用 和 #setMaximumPoolSize
動態#setCorePoolSize
變更。 </dd>
<dt>隨選建構</dt>
<dd>根據預設,即使是核心線程一開始也只會在新的工作到達時啟動,但可以使用 方法 #prestartCoreThread
或 #prestartAllCoreThreads
以動態方式覆寫。 如果您使用非空白佇列來建構集區,您可能想要預先啟動線程。 </dd>
<dt>建立新的線程</dt>
<dd>使用 建立 ThreadFactory
新的線程。 如果未指定,Executors#defaultThreadFactory
則會使用 ,將線程建立為相同且具有相同ThreadGroup
NORM_PRIORITY
優先順序和非精靈狀態的線程。 藉由提供不同的 ThreadFactory,您可以改變線程的名稱、線程群組、優先順序、精靈狀態等。 ThreadFactory
如果 當從傳回 null newThread
時無法建立線程,執行程式將會繼續執行,但可能無法執行任何工作。 線程應該擁有 「modifyThread」 RuntimePermission
。 如果使用集區的背景工作線程或其他線程沒有此許可權,服務可能會降級:組態變更可能無法及時生效,而且關機集區可能處於可能終止但無法完成的狀態。</dd>
<dt>Keep-alive times</dt>
<dd>如果集區目前有超過 corePoolSize 線程,如果線程已閒置超過 keepAliveTime,將會終止多餘的線程(請參閱 #getKeepAliveTime(TimeUnit)
)。 這提供在集區未主動使用時減少資源耗用量的方法。 如果集區稍後變成更作用中,將會建構新的線程。 您也可以使用 方法 #setKeepAliveTime(long, TimeUnit)
動態變更此參數。 使用的值 Long.MAX_VALUE
TimeUnit#NANOSECONDS
可有效停用閑置線程在關閉之前從未終止過。 根據預設,只有在有超過 corePoolSize 線程時,才能套用 keep-alive 原則,但方法 #allowCoreThreadTimeOut(boolean)
也可以用來將這個逾時原則套用至核心線程,只要 keepAliveTime 值不是零。 </dd>
<dt>Queuing</dt>
<dd>Any BlockingQueue
可用來傳輸和保存送出的工作。 使用此佇列會與集區重設大小互動:
<ul>
<li>如果執行的線程少於 corePoolSize 線程,則執行程式一律偏好新增線程,而不是佇列。
<li>如果 corePoolSize 或更多線程正在執行,執行程式一律偏好佇列要求,而不是新增線程。
<li>如果無法將要求排入佇列,除非這會超過 maximumPoolSize,否則會建立新的線程,在此情況下,將會拒絕工作。
</ul>
佇列有三個一般策略: <ol>
<li><em> Direct 交接。</em> 工作佇列的良好預設選擇是 SynchronousQueue
將工作交給線程,而不需加以控制。 在這裡,如果沒有任何線程立即可供執行工作,嘗試將工作排入佇列將會失敗,因此將會建構新的線程。 此原則會在處理可能有內部相依性的要求集時,避免鎖定。 直接交接通常需要未系結的 maximumPoolSizes,以避免拒絕新的提交工作。 這反過來又承認當命令平均到達速度比可處理快時,未系結線程成長的可能性。
<li><em> Unbounded queues.</em> 使用未系結的佇列(例如 LinkedBlockingQueue
沒有預先定義容量的 ),會導致當所有 corePoolSize 線程忙碌時,佇列中等待新的工作。 因此,永遠不會建立超過 corePoolSize 線程。 (因此 maximumPoolSize的值沒有任何作用。當每個工作完全獨立於其他人時,這可能很合適,因此工作不會影響彼此的執行;例如,在網頁伺服器中。 雖然這種佇列樣式有助於平移暫時性要求高載,但是當命令繼續平均到達速度比處理快時,它承認未繫結的工作佇列成長的可能性。
<li><em>Bounded queues.</em> 限定佇列(例如,a ArrayBlockingQueue
)有助於避免搭配有限 maximumPoolSizes 使用時的資源耗盡,但可能更難微調和控制。 佇列大小和集區大小上限可能會彼此取捨:使用大型佇列和小型集區可將 CPU 使用量、OS 資源和內容切換額外負荷降到最低,但可能會導致人為的低輸送量。 如果工作經常封鎖(例如,如果是 I/O 系結),系統可能會比您允許的線程還要多排程時間。 使用小型佇列通常需要較大的集區大小,讓 CPU 保持較忙碌,但可能會遇到無法接受的排程額外負荷,這也會降低輸送量。
</老>
</dd>
<dt>拒絕的工作</dt>
<dd>在 方法 #execute(Runnable)
中提交的新工作會在 <執行程式已關閉時為 em>rejected</em> ,而且當執行程式針對線程和工作佇列容量使用有限界限,而且已飽和時。 在這兩種情況下, execute
方法會 RejectedExecutionHandler#rejectedExecution(Runnable, ThreadPoolExecutor)
叫用其 RejectedExecutionHandler
的方法。 提供四個預先定義的處理程序原則:
<老>
<li>在預設 ThreadPoolExecutor.AbortPolicy
中,處理程式會在拒絕時擲回運行時間 RejectedExecutionException
。
<li>在 中 ThreadPoolExecutor.CallerRunsPolicy
,叫用本身的線程 execute
會執行工作。 這提供簡單的意見反應控制機制,可減緩提交新工作的速率。
<li>在 中 ThreadPoolExecutor.DiscardPolicy
,無法執行的工作只會卸除。 此原則只針對從未依賴任務完成的罕見案例所設計。
<li>In ThreadPoolExecutor.DiscardOldestPolicy
, if the executor is not shut down, the task at the head of the work queue is dropd, and then execution is retried (這可以再次失敗,導致重複執行。此原則很少可接受。 在幾乎所有情況下,您也應該取消工作以在任何元件中造成例外狀況,等待其完成,以及/或記錄失敗,如檔所述 ThreadPoolExecutor.DiscardOldestPolicy
。
</老>
可以定義和使用其他類型的 RejectedExecutionHandler
類別。 這樣做需要一些小心,特別是當原則設計為只在特定容量或佇列原則下運作時。 </dd>
<dt>Hook 方法</dt>
<dd>此類別提供 protected
可 #beforeExecute(Thread, Runnable)
覆寫的 和 #afterExecute(Runnable, Throwable)
方法,這些方法會在執行每個工作之前和之後呼叫。 這些可用來操作執行環境;例如,重新初始化 ThreadLocals、收集統計數據或新增記錄專案。 此外,可以覆寫 方法 #terminated
,以執行執行程式完全終止之後,必須完成的任何特殊處理。
如果攔截、回呼或 BlockingQueue 方法擲回例外狀況,內部背景工作線程可能會接著失敗、突然終止,並可能取代。</dd>
<dt>佇列維護</dt>
<dd>方法 #getQueue()
允許存取工作佇列,以便進行監視和偵錯。 強烈建議不要將此方法用於任何其他用途。 提供兩種方法, #remove(Runnable)
而且 #purge
可在大量佇列工作取消時協助儲存回收。</dd>
<dt>填海</dt>
<dd>不再在程式 em AND</em>> 中<參考的集區沒有剩餘的線程可以回收(垃圾收集),而不會明確關閉。 您可以使用零核心線程的下限和/或設定 #allowCoreThreadTimeOut(boolean)
,設定適當的保持運作時間,設定集區以允許所有未使用的線程最終死去。 </dd>
</dl>
<b>延伸模組範例。</b> 此類別的大部分擴充功能都會覆寫一或多個受保護的攔截方法。 例如,以下是新增簡單暫停/繼續功能的子類別:
{@code
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();
}
}
}}
已在1.5中新增。
的 java.util.concurrent.ThreadPoolExecutor
Java 檔。
此頁面的部分是根據 Android 開放原始碼專案所建立和共用的工作進行修改,並根據 Creative Commons 2.5 屬性授權中所述的詞彙使用。
建構函式
ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue) |
使用指定的初始參數、Executors#defaultThreadFactory 默認線程處理站和 ThreadPoolExecutor 建立新的 |
ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IRejectedExecutionHandler) |
使用指定的初始參數和 Executors#defaultThreadFactory 預設線程處理站,建立新的 |
ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IThreadFactory) |
使用指定的初始參數和 ThreadPoolExecutor 建立新的 |
ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IThreadFactory, IRejectedExecutionHandler) |
使用指定的初始參數建立新的 |
ThreadPoolExecutor(IntPtr, JniHandleOwnership) |
建立 JNI 物件的 Managed 表示法時使用的建構函式;由運行時間呼叫。 |
屬性
ActiveCount |
傳回正在執行工作的大約線程數目。 |
Class |
傳回這個 |
CompletedTaskCount |
傳回已完成執行之工作的近似總數。 |
CorePoolSize |
傳回線程的核心數目。 -或- 設定線程的核心數目。 |
Handle |
基礎Android實例的句柄。 (繼承來源 Object) |
IsShutdown |
, |
IsTerminated |
, |
IsTerminating |
如果這個執行程式在 或 |
JniIdentityHashCode |
, |
JniPeerMembers |
, |
LargestPoolSize |
傳回已同時在集區中的最大線程數目。 |
MaximumPoolSize |
傳回允許的線程數目上限。 -或- 設定允許的線程數目上限。 |
PeerReference |
, |
PoolSize |
傳回集區中目前線程數目。 |
Queue |
傳回這個執行程式所使用的工作佇列。 |
RejectedExecutionHandler |
傳回無法執行之工作的目前處理程式。 -或- 設定無法執行之工作的新處理程式。 |
TaskCount |
傳回已排程執行之工作的近似總數。 |
ThreadFactory |
傳回用來建立新線程的線程處理站。 -或- 設定用來建立新線程的線程處理站。 |
ThresholdClass |
此 API 支援適用於 Android 的 Mono 基礎結構,並不適合直接從您的程式代碼使用。 |
ThresholdType |
此 API 支援適用於 Android 的 Mono 基礎結構,並不適合直接從您的程式代碼使用。 |
方法
AfterExecute(IRunnable, Throwable) |
完成指定 Runnable 執行時叫用的方法。 |
AllowCoreThreadTimeOut(Boolean) |
設定原則,控制核心線程是否可能在保持運作時間內沒有工作到達時逾時和終止,並在新工作送達時視需要取代。 |
AllowsCoreThreadTimeOut() |
如果此集區允許核心線程逾時,如果keepAlive時間內沒有任何工作到達,則會傳回 true,並在新工作送達時視需要取代。 |
AwaitTermination(Int64, TimeUnit) |
, |
AwaitTerminationAsync(Int64, TimeUnit) |
, |
BeforeExecute(Thread, IRunnable) |
在指定線程中執行指定的 Runnable 之前叫用的方法。 |
Clone() |
建立並傳回這個 對象的複本。 (繼承來源 Object) |
Dispose() |
, |
Dispose(Boolean) |
, |
Equals(Object) |
指出其他物件是否「等於」這個物件。 (繼承來源 Object) |
Execute(IRunnable) |
在未來某個時候執行指定的工作。 |
GetHashCode() |
傳回此物件的雜湊碼值。 (繼承來源 Object) |
GetKeepAliveTime(TimeUnit) |
傳回線程保持運作時間,這是線程在終止之前可能保持閑置的時間量。 |
InvokeAll(ICollection) |
, |
InvokeAll(ICollection, Int64, TimeUnit) |
, |
InvokeAny(ICollection) |
, |
InvokeAny(ICollection, Int64, TimeUnit) |
, |
JavaFinalize() |
當垃圾收集決定不再參考物件時,垃圾收集行程在 物件上呼叫。 (繼承來源 Object) |
NewTaskFor(ICallable) |
傳 |
NewTaskFor(IRunnable, Object) |
傳 |
Notify() |
喚醒正在等候此物件監視器的單一線程。 (繼承來源 Object) |
NotifyAll() |
喚醒正在等候此物件監視器的所有線程。 (繼承來源 Object) |
PrestartAllCoreThreads() |
啟動所有核心線程,導致它們暫時等候工作。 |
PrestartCoreThread() |
啟動核心線程,導致其閑著等候工作。 |
Purge() |
嘗試從工作佇列中移除所有 |
Remove(IRunnable) |
如果執行程式的內部佇列存在,則從執行程式的內部佇列中移除此工作,因此如果尚未啟動,則不會執行工作。 |
SetHandle(IntPtr, JniHandleOwnership) |
設定 Handle 屬性。 (繼承來源 Object) |
SetKeepAliveTime(Int64, TimeUnit) |
設定線程保持運作時間,這是線程在終止之前可能保持閑置的時間量。 |
Shutdown() |
起始依序關閉,在其中執行先前提交的工作,但不會接受任何新工作。 |
ShutdownNow() |
嘗試停止所有主動執行的工作、停止等候工作的處理,並傳回正在等候執行的工作清單。 |
Submit(ICallable) |
, |
Submit(IRunnable) |
提交可執行的工作以供執行,並傳回代表該工作的 Future。 (繼承來源 AbstractExecutorService) |
Submit(IRunnable, Object) |
, |
Terminated() |
執行程序終止時叫用的方法。 |
ToArray<T>() |
, |
ToString() |
傳回物件的字串表示。 (繼承來源 Object) |
UnregisterFromRuntime() |
, |
Wait() |
讓目前線程等候直到喚醒為止,通常是藉由em <notified/em>或<em>interrupted</em> 來喚醒它。<> (繼承來源 Object) |
Wait(Int64) |
讓目前的線程等到喚醒為止,通常是因為 <em>notified</em> 或 <em>interrupted</em>,或直到經過一定數量的實時為止。 (繼承來源 Object) |
Wait(Int64, Int32) |
讓目前的線程等到喚醒為止,通常是因為 <em>notified</em> 或 <em>interrupted</em>,或直到經過一定數量的實時為止。 (繼承來源 Object) |
明確介面實作
IJavaPeerable.Disposed() |
, |
IJavaPeerable.DisposeUnlessReferenced() |
, |
IJavaPeerable.Finalized() |
, |
IJavaPeerable.JniManagedPeerState |
, |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
, |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
, |
IJavaPeerable.SetPeerReference(JniObjectReference) |
, |
擴充方法
JavaCast<TResult>(IJavaObject) |
執行 Android 執行時間檢查的類型轉換。 |
JavaCast<TResult>(IJavaObject) |
, |
GetJniTypeName(IJavaPeerable) |
, |
AwaitTerminationAsync(IExecutorService, Int64, TimeUnit) |
, |
InvokeAnyAsync(IExecutorService, ICollection) |
, |
InvokeAnyAsync(IExecutorService, ICollection, Int64, TimeUnit) |
, |