2017-05-08 5 views
0

すべてのメソッド呼び出しで新しいExecutorServiceを作成するか、クラスごとに1つずつ使う必要がありますか?パフォーマンスの面で好ましい選択肢はどれですか?あなたの最初のコードでExecutorService - クラスごとに1つのメソッドに対して新しいインスタンスを作成する

public class NotificationService { 

    public void sendNotification(User recipient) { 

     ExecutorService notificationsPool = Executors.newFixedThreadPool(10); 

     // code 

     notificationsPool.shutdown(); 
    } 
} 

それとも

public class NotificationService { 

    ExecutorService notificationsPool = Executors.newFixedThreadPool(10); 

    public void sendNotification(User recipient) { 

     // code 
    } 
} 
+2

パフォーマンスに基づいてこれを選択しないでください。あなたは必要なものに基づいてこれを選択します。ユーザーに通知を送信するために10個の新しいスレッドが必要ですか?それらのうちの1つだけを使用すれば、再利用可能なスレッド10個のプールを1つだけ持つことができます(ユーザーに通知を送信すると仮定した場合)。 –

+0

ユーザーは複数のキーと関連している可能性があります。しかし、投稿前に変更された良いコード例ではありません。 – Justas

答えて

1

ExecutorServiceは、すなわち新しいExecutorServiceは、各メソッドの呼び出しで作成され、ExecutorServiceは、メソッドの最後に終了し、ローカルでスニペット。結果として、メソッドが次回実行されたときにスレッドが再利用されることはありません。 2番目のスニペットでは、ExecutorServiceとそのスレッドは、NotificationServiceインスタンスが存続している限り保持されます。ご覧のとおり、ExecutorServiceのインスタンス数が少なくなるだけでなく、作成するスレッドが少なくて済み、再利用することができます。追加のボーナスとして、ExecutorServiceが作成された後、2番目の方法ではスレッドの作成にウォーミングアップ時間が発生しません。

NotificationServiceのインスタンスが複数ある場合は、notificationsPoolstaticと宣言して、すべてのインスタンス間でプールとそのスレッドを共有する必要があります。

送信する必要がある通知の量によって必要なスレッドの量が異なる場合は、キャッシュされたスレッドプール(ExecutorService#newCachedThreadPool())を使用してください。

1

これは二つの質問に依存します:あなたは並列化の

  • 何年生が必要なのですか?
  • どのくらいのオーバーヘッドが許容されますか?

機能の問題を解決するには本当に10スレッドが必要ですか?そして、関数を2回処理する必要がありますか(つまり、スレッドを20個与えます)?あなたはそうするために資源を持っていますか?

または、クラスにthreadPoolを割り当てるとどうなりますか?スレッドプールが使い果たされているためにブロックすることで問題に遭遇しますか?

十分なリソースがあれば、オプション1は、解決しようとするタスクが、関数が呼び出されるたびにそのエグゼキュータを作成することによるオーバーヘッドを正当化するのに十分なほど大きい場合があります。正直なところ、私はそれほど激しい通知を想像することはほとんどありません。

これ以上の情報がなければ、私はオプション2(もちろん静的であると仮定します)を指摘します。また、新しいWorkStealingPoolを見てみると、正確なレベルの並列処理を使用するのに役立ちます。

関連する問題