7

私のコード:


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()はループまたは待機でのみ機能するメソッドのみを使用します. したがって、この瞬間が発生した場合、タイムアウトは機能しません。それで、どうやって?

4

6 に答える 6

11

スレッドが定期的に isInterrupted() フラグをチェックする (または割り込み可能なメソッドで待機している、つまり InterruptedException をスローする) 場合を除き、スレッドの即時終了は保証されません。

ワーカー スレッドが定期的に isInterrupted() をチェックするように実装することを検討してください。これは次のようなものかもしれません:

public void run() { 
  byte[] data;
  do {
     data = receiveDataChunk(timeout);
     processData(data);
  } while(!isInterrupted() && data != null);
}
于 2011-05-10T07:44:45.880 に答える
6

ExecutorService.shutdownNow()実行中のすべてのスレッドを停止しようとします。

これはjavadocからの引用です

List<Runnable> shutdownNow()

アクティブに実行中のすべてのタスクの停止を試み、待機中のタスクの処理を停止し、実行を待機していたタスクのリストを返します。

アクティブに実行中のタスクの処理を停止するための最善の努力以外の保証はありません。たとえば、一般的な実装は Thread.interrupt() を介してキャンセルされるため、タスクが割り込みをマスクしたり、応答に失敗したりした場合、それらのタスクは決して終了しない可能性があります。

于 2011-05-10T07:31:03.100 に答える
6

torrent のダウンロードにはおそらく IO 操作のブロックが含まれるため、単純にcancel()/shutdownNow()を呼び出すだけでは十分ではありません。これは、それぞれのスレッドが中断されたときに IO 操作のブロックが終了することが保証されていないためです。

ブロッキング IO をキャンセルするには、基盤となるソケットを閉じる必要もあります。ソケット IO 操作でスレッドのブロッキングを即座に終了する方法を参照してください .

于 2011-05-10T07:46:11.270 に答える
-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");
于 2013-01-19T16:30:57.850 に答える