2015-11-17 28 views
5

キャッシュされたスレッドプールを作成したいが、固定されたスレッドプールを作成する。現在、私はこのコードを持っている:私は、コードを実行した場合スレッドプールのサイズが変更されない

public class BackgroundProcesses { 

    public static void main(String[] args) throws InterruptedException, ExecutionException { 
     //ExecutorService threadPool2 = Executors.newCachedThreadPool(); 
     ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); 
     for (int i = 0; i < 800; i++) { 
      Callable<String> task = new Task(); 
      threadPool.submit(task); 
     } 
    } 
} 

class Task implements Callable<String> { 

    @Override 
    public String call() throws Exception { 
     Thread.sleep(100); 
     System.out.println(Thread.currentThread().getName() + " is ready"); 
     return ""; 
    } 
} 

私は出力を得る:

pool-1-thread-1 is ready 
pool-1-thread-2 is ready 
pool-1-thread-1 is ready 
pool-1-thread-2 is ready 
... 

はわずか2スレッドがすべての作業をやっているし、新しいワーカースレッドがプールに追加されません意味します。タスクがキュー内で待機している場合(私の場合は最大10個)、スレッドプールがさらにスレッドを生成すべきではありませんか?

Executors.newCachedThreadPool()は、最大スレッドの上限が実質的になく、corePoolSizeであるため、使用したくありません。応答性向上のために常にスレッドを準備したいと考えています。 1 -----

-----編集は答えのためにあなたのアレクセイありがとうございます。キューの容量を設定することで、期待どおりの動作をさせるようになりましたが、今は新しい問題があります。

バックグラウンドタスクの量は大きく異なります。ほとんどの場合0ですが、短期間に最大50の同時タスクを実行できます。これを処理する効率的な方法は何でしょうか?ほとんどのバックグラウンドタスクは短命(< 1秒)ですが、長寿命のタスク(> 1分)もいくつかあります。私はこのように私のスレッドプールを設定した場合

ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10)); 

私が最も可能性の高いピーク使用してRejectedExecutionExceptionを取得します。しかし、スレッドプールを次のように設定した場合:

ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200)); 

キューが最大にならないため、新しいワーカースレッドは追加されません。

CPUには少なくとも4つのコアがあるため、これは私の意見では無駄です。そして、ほとんどの場合、バックグラウンドタスク(アップタイムの80%)はほとんどないので、固定スレッドプールを維持することは、私の意見では無駄になります。

答えて

4

ThreadPoolExecutorのJavadocは言う:新しいタスクが方法で提出された場合(Runnableを)実行

、およびcorePoolSizeスレッドが実行されているよりも 少ない、新しいスレッドを でも、他の場合には、要求を処理するために作成されますワーカースレッドはアイドル状態です。 がcorePoolSizeよりますがmaximumPoolSizeスレッド ランニング未満がある場合は、新しいスレッドは、キューが、それは数の上限を持っていないので、あなたのLinkedBlockingQueueは、いっぱいになることはありません

いっぱいになった場合にのみ作成されます要素の new LinkedBlockingQueue()から new LinkedBlockingQueue(10)に変更すると解決します。

+0

これをクリアしていただきありがとうございます。キューがいっぱいになり、すべてのアクティブなスレッドも使用されているので、今私はRejectedExecutionException(プールサイズ= 10、アクティブなスレッド= 10、キューに入れられたタスク= 10)を取得しています。 –

関連する問題