簡體   English   中英

具有有限線程數的執行程序

[英]Executor with limited thread count on demand

我正在尋找一個ExecutorService ,它按需創建線程達到預定義的限制,並在保持活動時間后銷毀空閑線程。

以下構造函數創建一個具有固定線程數的ThreadPoolExecutor

// taken from Executors.newFixedThreadPool()
new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());

所以我試着用這種方式創建一個ExecutorService

// taken from Executors.newCachedThreadPool()
new ThreadPoolExecutor(0, nThreads,
    CACHED_POOL_SHUTDOWN_DELAY, TimeUnit.SECONDS,
    new SynchronousQueue<Runnable>());

但它沒有按預期工作,當nThreads正在使用時, Executor不會將新任務排入nThreads ,但會拋出RejectedExecutionException 我知道我可以為此實現一個處理程序,但它對我沒有幫助。

如何創建前面描述的Executor

如果新任務無法排隊,則會創建新線程,除非您已達到最大核心池大小。 在您的情況下,隊列一次只能包含一個任務,因此如果您足夠快地提交任務,則達到最大池大小並獲得異常。

它適用於CachedThreadPool,因為最大核心池大小很大( Integer.MAX_VALUE )。

您需要使用不同的隊列,例如固定線程LinkedBlockingQueue示例中的新LinkedBlockingQueue

附注:檢查實施文檔有助於了解詳細信息。 特別是, ThreadPoolExecutor類的execute方法具有:

   /*
     * Proceed in 3 steps:
     *
     * 1. If fewer than corePoolSize threads are running, try to
     * start a new thread with the given command as its first
     * task.  The call to addWorker atomically checks runState and
     * workerCount, and so prevents false alarms that would add
     * threads when it shouldn't, by returning false.
     *
     * 2. If a task can be successfully queued, then we still need
     * to double-check whether we should have added a thread
     * (because existing ones died since last checking) or that
     * the pool shut down since entry into this method. So we
     * recheck state and if necessary roll back the enqueuing if
     * stopped, or start a new thread if there are none.
     *
     * 3. If we cannot queue task, then we try to add a new
     * thread.  If it fails, we know we are shut down or saturated
     * and so reject the task.
     */

我在那篇帖子上發現了一種方法,它正是我所需要的。
@assylias我認出你的答案並改變了隊列實現。

現在我的代碼看起來像這樣:

parallelExecutor = new ThreadPoolExecutor(nThreads, nThreads,
    CACHED_POOL_SHUTDOWN_DELAY, TimeUnit.SECONDS,
    new LinkedBlockingQueue<Runnable>());

parallelExecutor.allowCoreThreadTimeOut(true);   // this is the magic

它的工作方式類似於固定的線程池,但允許這些核心超時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM