2011-05-10 15 views
4

マイコード:Javaは:フォースExecutorServiceのスレッドの停止


String[] torrentFiles = new File("/root/torrents/").list(); 

     if(torrentFiles.length == 0 || torrentFiles == null) 
     { 
      System.exit(0); 
     } 

     ex = Executors.newFixedThreadPool(3); 

     for(String torrentFile : torrentFiles) 
     { 
      ex.submit(new DownloadTorrent("/root/torrents/" + torrentFile)); 
     } 

     ex.shutdown(); 

     try 
     { 
      ex.awaitTermination(30, TimeUnit.MINUTES); 
     } 
     catch(InterruptedException ex1) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex1); 
     } 

しかし、時には急流のダウンロードは未知の時間値を取り、«awaitTermination»私が望むように動作しません。私はすべての実行スレッドを30分後に即座に停止する必要がありますが、私が知っているように«awaitTermination»ちょうどinterrupt()ループまたは待機中の方法を使用してください。だからこの瞬間が起これば、タイムアウトはうまくいかない。だから、どのように?

答えて

6

ExecutorService.shutdownNow()はここ

...すべての実行中のスレッドを停止しようとしたjavadocからの引用のすべての積極的 実行中のタスクを停止する

List<Runnable> shutdownNow()

試みは、の処理 を停止しています の実行を待機していたタスクのリスト を返します。

ベストエフォート型の試みを超えて、アクティブに実行されているタスクを処理しようとする試みを超えた保証はありません。 たとえば、一般的な実装 はThread.interrupt()を介してキャンセルされるため、 タスクがマスクするか、または が割り込みに応答しないと、 が終了しないことがあります。

+1

shutdownNow()を使用して他の実行中のスレッドをすべて停止していますが、サービス応答を待っているスレッドを停止できます。スレッドをスリープ状態にするとすぐに停止しますが、以前のケースではスレッドは停止しません。具体的な理由はありますか? – Akshay

+0

@Akshay - はい、それが起こった理由があります。 Thread.sleep()は割り込みステータスをチェックし、すでに割り込みが発生している場合はInterruptedExceptionをスローします。しかし、このようなブロッキングが起こっていない場合、docに記載されているように、積極的に実行中のタスクの処理を最善の努力で止めることはできません。 – skm

1

ExecutorService.submit(...)cancel()メソッドを持つFuture<?>を返します。それぞれのタスクを停止させたいときは、これらのタスクを呼び出すことができます。

+8

実装でThread.interrupted()のチェックを実装していない場合、これは効果がありません。 – pintxo

7

スレッドがisInterrupted()フラグを定期的にチェックしていないか、割り込み可能なメソッドで待機している、つまりInterruptedExceptionをスローしていない限り、インスタントスレッド終了は保証されません。

isInterrupted()を定期的にチェックするときにワーカースレッドを実装することを検討してください。おそらく急流のダウンロードはIO操作をブロック伴うので、それぞれのスレッドが中断されたときに、ブロッキングIO操作が終了することが保証されていないので、単にcancel()/shutdownNow()を呼び出すと、十分ではないでしょう

public void run() { 
    byte[] data; 
    do { 
    data = receiveDataChunk(timeout); 
    processData(data); 
    } while(!isInterrupted() && data != null); 
} 
-1

今はプールからスレッドを停止する必要があります。私はそんなやり方をしている。それは良い考えではないかもしれません。もしそうなら、コメントしてください。

boolean isTerminated = mPoolThreads.isTerminated(); 
while (!isTerminated) { 
    mPoolThreads.shutdownNow(); 
    isTerminated = mPoolThreads.isTerminated(); 
    Log.i(Constants.LOG_TAG, "Stop threads: the threads are not terminated yet"); 
} 
Log.w(Constants.LOG_TAG, "Stop threads: Terminated"); 
+0

私は直接の質問についてはわかりませんが、whileループの代わりにそのような場合にはよりよいパターン(終了するコードを見るだけではわからない)は、例えば'for(int retries = 0;再試行<1000; ++再試行)'。また、再試行の間、または少なくとも['yield()'](10秒待機)を追加してください(http://stackoverflow.com/a/6979859/1143274)。 1000に達した場合は、エラーをログに記録します。 (1000の代わりに、それが正しく動作するならば、期待するのは全く無理があります)。 –

0

amこのコードを使用して作成しました。

wkhtmltopdfを使用して、多くのhtmlテンプレートから多数のpdfファイルを生成しています。

私はクライアントを待たずにハンドレッドを作成するパフォーマンスを向上させたいと考えていますが、これは実装の一部に過ぎません。

getListOfCallables固定プールの作成で使用するスレッドの数に応じて、最適な のしきい値が戻されます。

私はそれを囲んでいるデッドスレッドをたくさん持っていることを扱うことができないので、私のEC2 CPUが100%スタックした。

私が使用:

  • シャットダウン()
  • shutdownNowのを()
  • shutdownNowの()例外一部で

一覧fileGenerationHtmlToPdfList = getListOfCallables(パス、名前、待つの他にオプション);

  ExecutorService executorService = Executors.newFixedThreadPool(fileGenerationHtmlToPdfList.size()); 


      List<Future<ArrayList<File>>> futures = null; 

      try { 
       futures = executorService.invokeAll(fileGenerationHtmlToPdfList); 
       try { 
        for(Future f: futures) { 
         files.addAll((ArrayList<File>)f.get()); 
        } 

       } catch (InterruptedException ex) { 
        Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex); 
       } catch (ExecutionException ex) { 
        Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex); 
       } 
      } catch (InterruptedException ex) { 
       Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex); 
      } 

executorService.shutdown();//try shutdown 

      try { 
       if (executorService.awaitTermination(5, TimeUnit.SECONDS)) { 
        Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Done ShutDowned"); 
       } else { 
        executorService.shutdownNow(); 
       } 
      } catch (InterruptedException ex) { 
       executorService.shutdownNow(); 
       Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex); 
      } 
関連する問題