2016-03-25 25 views
3

私は、JavaでThreadPoolExecutorを使用してマルチスレッドを実行しています。スレッド終了後に何かをしなければならず、待たなければなりません。JavaでThreadPoolExecutorの終了スレッドを待つ最善の方法は何ですか?

だから私はそれを行うための最善の方法は何ですか?

私は途方もないでしょうか?

threadPool.shutdown(); 

boolean loop = true; 
Integer x = threadPool.getPoolSize(); 
while (threadPool.getPoolSize() != 0) { 
} 

答えて

1

シャットダウンは以前に提出したタスクが実行される通常のシャットダウンを開始しますが、新しいタスクは受け入れられません。これは、いずれか早い方、すべてのタスクがシャットダウン要求後に実行が完了した、またはタイムアウトが発生した場合、または現在のスレッドが中断されるまで、現在のスレッドをブロックすることができますよう

executor.shutdown(); 
    System.out.println("All tasks submitted...No new tasks will be admitted"); 

しかし、私は強くawaitTerminationを使用することをお勧めします。

try { 
     executor.awaitTermination(3, TimeUnit.SECONDS); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

EDIT:これらの値の事項のうち

The runState provides the main lifecyle control, taking on values: 

* RUNNING: Accept new tasks and process queued tasks 
* SHUTDOWN: Don't accept new tasks, but process queued tasks 
* STOP:  Don't accept new tasks, don't process queued tasks, 
*    and interrupt in-progress tasks 
* TIDYING: All tasks have terminated, workerCount is zero, 
*    the thread transitioning to state TIDYING 
*    will run the terminated() hook method 
* TERMINATED: terminated() has completed 

数字の順番は、注文した比較ができるようにします。 runStateは時間とともに単調に増加しますが、各状態に達する必要はありません。 遷移は、次のとおり

RUNNING - > SHUTDOWNシャットダウン(の呼び出しで
)、おそらく暗黙ファイナライズ()

(RUNNINGまたはSHUTDOWN)における - > STOP
オンshutdownNow()の呼び出し

シャットダウン - > TIDYING
キューとプールの両方が

STOP空である - >終了()フックメソッド
末端 - >
プールが空である

片付けを片付け完了しました。 awaitTermination()で待機しているスレッドは、状態がTERMINATEDに達したときに戻ります。キューは、SHUTDOWN状態の時に空でないと、その逆の後に空になるかもしれませんが、我々は唯一それが空であることを見た後、場合に終了することができますので、SHUTDOWNから片付けへの移行を検出

は、あなたが希望よりも簡単です。私たちはworkerCountが0であることを確認します。

getPoolSize()を呼び出すと、TIDYING状態のスレッドプールの状態をチェックします。したがって、正しいチェックはTERMINATED状態でなければならないと思います。ただし、terminated()メソッドを実装していないと結果は同じです。

+0

こんにちは、スカルナは「よくない」ですか?どうして? – jsohpill

+0

2つの理由があります。1.スレッドプールが実行を完了するまで、 'while loop'がCPUバインドされます。一方、awaitTermination 2ではそうではありません。getPoolSize()を使用すると、エグゼキュータの状態はまだ終了していません。ただし、terminated()呼び出しを実装していない可能性があります。しかし、#1のために、私はawaitTerminationをwhileループで推薦します。 – Suparna

+0

しかし、tryを使用するとすべてのスレッドが終了するのを待つことはできません{ executor.awaitTermination(3、TimeUnit.SECONDS); } catch(InterruptedException e){ e.printStackTrace(); }。メインプロセスはそのあとでコードを実行し続けます。スレッドが終了する前にメインプロセスを停止してから実行しなければならないようです。 – jsohpill

1

あなたは優雅に待ちたい場合は、下記の質問に解決策を参照してください。あなたがそれらのいずれか(invokeAllCountDownLatch)を使用してジョブを送信し、フィニッシュまで執行を待っていない場合

How to wait for completion of multiple tasks in Java?

:タスクは、このケースで

How to forcefully shutdown java ExecutorService

Basicのコードスニペットを参照してください。

void shutdownAndAwaitTermination(ExecutorService pool) { 
    pool.shutdown(); // Disable new tasks from being submitted 
    try { 
    // Wait a while for existing tasks to terminate 
    if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { 
     pool.shutdownNow(); // Cancel currently executing tasks 
     // Wait a while for tasks to respond to being cancelled 
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) 
      System.err.println("Pool did not terminate"); 
    } 
    } catch (InterruptedException ie) { 
    // (Re-)Cancel if current thread also interrupted 
    pool.shutdownNow(); 
    // Preserve interrupt status 
    Thread.currentThread().interrupt(); 
    } 
関連する問題