web-dev-qa-db-ja.com

Executors.newFixedThreadPool(1)とExecutors.newSingleThreadExecutor()の違い

私の質問は:Executors.newFixedThreadPool(1)??を使用するのは理にかなっていますか。 2つのスレッド(メイン+ oneAnotherThread)のシナリオでは、エグゼキューターサービスを使用するのが効率的ですか? ExecutorServiceを使用するよりも、new Runnable(){ }を呼び出して新しいスレッドを直接作成する方がよいでしょうか?このようなシナリオでExecutorServiceを使用することのメリットとデメリットは何ですか?

PS:メインスレッドとoneAnotherThreadは、共通のリソースにアクセスしません。

私は経験しました: ExecutorServiceを使用する利点は何ですか? 。および 一度に1つのスレッドのみ!

18
TheLostMind

Executors.newFixedThreadPool(1)を使用するのは理にかなっていますか?

javadoc に示されているように、後者は再構成できないことを除いて、基本的にExecutors.newSingleThreadExecutor()と同じですが、前者はThreadPoolExecutor

2つのスレッド(メイン+ oneAnotherThread)のシナリオでは、エグゼキューターサービスを使用するのが効率的ですか?

エグゼキュータサービスは、スレッドのライフサイクル管理を大幅に容易にするスレッドの非常に薄いラッパーです。必要なのがnew Thread(runnable).start();で先に進むことだけである場合、ExecutorServiceは実際には必要ありません。

ほとんどの実際のケースでは、タスクのライフサイクルを監視する可能性(返されたFuturesを介して)、キャッチされない例外の場合にエグゼキュータが必要に応じてスレッドを再作成するという事実、パフォーマンスの向上スレッドのリサイクルと新しいスレッドの作成などの違いにより、エグゼキュータサービスはわずかな追加コストではるかに強力なソリューションになります。

結論:エグゼキュータサービスを使用することとスレッドを使用することのデメリットは見られません。

Executors.newSingleThreadExecutor()。execute(command)とnew Thread(command).start(); の違いは、2つのオプション間の動作のわずかな違いです。

16
assylias

executors.newFixedThreadPool(1)を使用するのは理にかなっていますか?

はい。送信されたすべてのタスクを到着順に処理する場合は理にかなっています

2つのスレッド(メイン+ oneAnotherThread)のシナリオでは、エグゼキューターサービスを使用するのが効率的ですか? ExecutorServiceを使用するよりも、new Runnable(){}を呼び出して新しいスレッドを直接作成する方がよいでしょうか。

1つのスレッドでもExecutorServiceまたはThreadPoolExecutorが好きです。

新しいRunnable()に対するThreadPoolExecutorの利点の説明については、以下のSEの質問を参照してください。

ExecutorServiceとカジュアルスレッドスポナー

このようなシナリオでExecutorServiceを使用することのメリットとデメリットは何ですか?

ExexutorServiceのユースケースに関する関連するSEの質問をご覧ください。

JavaのFork/Join vs ExecutorService-いつどちらを使用するか?

件名のクエリ( grepcode から)に関しては、どちらも同じです。

newFixedThreadPool AP​​Iは、ThreadPoolExecutorをExecutorServiceとして返します。

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

そして

newSingleThreadExecutor() ThreadPoolExecutorをExecutorServiceとして返します:

_public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
_

類似点/相違点に関する@assyliasの回答に同意します。

1
Ravindra babu

キュー内のタスクの数を決定するためにExecutors.newFixedThreadPool(1)を使用する必要がある場合があります

private final ExecutorService executor = Executors.newFixedThreadPool(1);

public int getTaskInQueueCount() {
    ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
    return threadPoolExecutor.getQueue().size();
}
1
v.ladynev

ExecutorServiceを使用するよりも、new Runnable(){}を呼び出して新しいスレッドを直接作成する方がよいでしょうか。

スレッドのコンパイル後に返された結果で何かを計算する場合は、Callableインターフェイスを使用できます。これは、新しいRunnable(){}ではなくExecutorServiceでのみ使用できます。 Callableオブジェクトを引数として取るExecutorServiceのsubmit()メソッドは、Futureオブジェクトを返します。このFutureオブジェクトで、isDone()メソッドを使用せずにタスクが完了したかどうかを確認します。また、get()メソッドを使用して結果を取得することもできます。この場合、ExecutorServiceは新しいRunnable(){}よりも優れています。

0
KayV