37

私はマルチスレッドプロジェクトで作業しています。マルチスレッドプロジェクトでは、ロードとパフォーマンスのテストを行っているときに、クライアントコードのエンドツーエンドのパフォーマンスを測定するために複数のスレッドを生成する必要があります。だから私はExecutorService使用しているコードの下に作成 -ExectuorServiceとThreadPoolExecutor(これはLinkedBlockingQueueを使用しています)

を以下ExecutorService使用されるコードである -

public class MultithreadingExample { 

    public static void main(String[] args) throws InterruptedException { 

     ExecutorService executor = Executors.newFixedThreadPool(20); 
     for (int i = 0; i < 100; i++) { 
      executor.submit(new NewTask()); 
     } 

     executor.shutdown(); 
     executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    } 
} 

class NewTask implements Runnable { 

    @Override 
    public void run() { 
     //Measure the end to end latency of my client code 
    } 
} 

問題文を: -

は、今私は、インターネット上でいくつかの記事を読んでいました。私はそこにあることを知った。

ThreadPoolExecutorも同様である。だから、私はどちらを使うべきか混乱した。

私は上記のコードfrom-

ExecutorService executor = Executors.newFixedThreadPool(20); 
    for (int i = 0; i < 100; i++) { 
     executor.submit(new NewTask()); 
    } 

任意の違いを生むだろう、その後

BlockingQueue<Runnable> threadPool = new LinkedBlockingQueue<Runnable>(); 

ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L, TimeUnit.MILLISECONDS, threadPool); 

tpExecutor.prestartAllCoreThreads(); 

    for (int i = 0; i < 100; i++) { 
     tpExecutor.execute(new NewTask()); 
    } 

ツー・交換した場合は?私はThreadPoolExectuorを使用して貼り付けたExecutorServiceと新しいコードを使用して私の元のコードの違いは何ですか?私のチームメイトの中には、2番目のもの(ThreadPoolExecutor)が正しい方法であると言われていますか?

誰でも私のためにこのことを明確にすることはできますか?助けてくれてありがとう。

答えて

19

それでは違いはありますか?

これは、コードを少し利益のためにもっと複雑にします。

私は、ExecutorServiceと新しいコードを使用しているオリジナルコードと、ThreadPoolExectuorを使用して貼り付けた新しいコードとの違いを理解しようとしていますか?

次は何もありません。 Executorsは、実際の作業を行うThreadPoolExecutorを作成します。

私のチームメイトの中には、2番目のもの(ThreadPoolExecutor)が正しい方法であると言われていますか?

ちょうど複雑であるからといって、それは正しいことではありません。デザイナーは、Executors.newXxxxメソッドを提供して、人生をよりシンプルにし、それらのメソッドを使用することを期待していました。私はあなたもそれらを使用することをお勧めします。

+0

あなたは少し利益について話しましたか?それはどういうことですか?そして、ExecutorはThreadPoolExecutorという名前のシーンの背後にいますか?しかし、私はそれは私が推測するわずかに遅い無制限のキューを使用すると思いますか?私が間違っているなら、私を訂正してください。 –

+0

小さな利点は、コンストラクタの引数を使って遊ぶことができますが、これは通常良い考えではありません。あなたは同じ無制限のキューを提供していますので、私はあなたのポイントを見ません。それが遅いなら、なぜデザイナーはそれを使用するでしょうか? –

+0

LinkedBoundedQueueの使用にはコストがかかります。それは無限であるという事実とは無関係であり、あなたがあまり心配していないと思うスレッド間でタスクを渡すコストに比べて非常に小さいです。 –

7
  1. Executors#newFixedThreadPool(int nThreads)

    ExecutorService executor = Executors.newFixedThreadPool(20); 
    

基本的

return new ThreadPoolExecutor(20, 20, 
            0L, TimeUnit.MILLISECONDS, 
            new LinkedBlockingQueue<Runnable>()); 
あります。第2のケースで

BlockingQueue<Runnable> threadPool = new LinkedBlockingQueue<Runnable>(); 
ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L, 
    TimeUnit.MILLISECONDS, threadPool); 

、あなたはちょうど私があなたが必要とすることはないだろうこれは、2000年にmaxPoolSizeが増加しています。ここで

58

Executors.newFixedThreadPoolの源である:

public static ExecutorService newFixedThreadPool(int nThreads) { 
    return new ThreadPoolExecutor(nThreads, nThreads, 
            0L, TimeUnit.MILLISECONDS, 
            new LinkedBlockingQueue<Runnable>()); 
} 

あなたは上記を参照できるようこれは、内部的にデフォルト設定でThreadPoolExecutorクラスを使用しています。現在、デフォルトの設定がLinkedBlockingQueueの代わりに適しているシナリオがあります。優先度キューを使用する必要があるなどです。そのような場合、呼び出し側は、ThreadPoolExecutorを直接インスタンス化し、目的の設定を渡すことで直接作業できます。

4

RejectionHandlerを使用するともう1つの利点があると思います。

1

間違っている場合GC out of memory exceptionの2日後、私を修正し、ThreadPoolExecutorは私の命を救いました。 :)

のBalajiが言ったように、

は[..]もう一つの利点は、RejectionHandlerです。

私のケースでは、私は多くのRejectedExecutionExceptionを持っていましたが、廃棄ポリシーがすべての私の問題を解決しました。

private ThreadPoolExecutor executor = new ThreadPoolExecutor(1, cpus, 1, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ThreadPoolExecutor.DiscardPolicy()); 

注意してください。それはあなたがエグゼキュータに提出すべてスレッドを実行しない必要性を行う場合にのみ機能します。最初の例ではDarren's answer

0

を見て、あなたが2番目の例では、以下のステートメントを使用してちょうど20スレッド

ExecutorService executor = Executors.newFixedThreadPool(20); 

を作成しているThreadPoolExecutor、あなたがスレッドの制限は、の範囲で設定しているの詳細については

ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L, TimeUnit.MILLISECONDS,threadPool); 

20 to 2000間のより多くのスレッドがproceのために用意されていssing。しかし、タスクキューを無制限キューとして構成しています。

ThreadPoolExecutorは、以下のパラメータの多くまたはすべてをカスタマイズした方が効果的です。あなたがmax capacity for workQueueを設定し、エグゼキュータに提出されたタスクの数を超えるworkQueue容量のとき

ThreadPoolExecutor(int corePoolSize, 
       int maximumPoolSize, 
       long keepAliveTime, 
       TimeUnit unit, 
       BlockingQueue<Runnable> workQueue, 
       ThreadFactory threadFactory, 
       RejectedExecutionHandler handler) 

RejectedExecutionHandlerは有用であろう。

は、より多くの詳細については、ThreadPoolExecutorで拒否されたタスクのセクションを見てください。

関連する問題