5

を使用していくつかのスレッドを実行し、次のExecutorServiceように終了するまで待機するアプリケーションを作成しました。

ExecutorService exService;
exService = Executors.newCachedThreadPool();
exService.execute(T1);
exService.execute(T2);
exService.shutdown();
boolean finshed = exService.awaitTermination(5, TimeUnit.MINUTES);

時々、これらのスレッドの実行をキャンセルする必要があります (全体ExecutorService)。
試してみましたが、スレッドexService.shutdownNow()がスローjava.lang.InterruptedExceptionされ、キャンセルされません。
これらのスレッドの実行をキャンセルするにはどうすればよいですか?


編集: nanda の要求として追加された T1 クラス コード

public class TC implements Runnable{
    private ExtractedDataBuffer Buffer;
    private Scraper scraper;
    private String AppPath;
    private boolean Succeed=false;
    private Map<String,Object> Result=null;
    private JLabel StatElement;

    public TC(ExtractedDataBuffer Buffer,String AppPath,String XMLfile,JLabel Stat) throws FileNotFoundException {
        this.Buffer = Buffer;
        this.AppPath=AppPath;
        this.StatElement=Stat;

        ScraperConfiguration config;
        config = new ScraperConfiguration(AppPath + Main.XMLFilesPath +XMLfile);
        scraper = new Scraper(config, AppPath);
    }

    private void extract(){
        try{
            mainF.SetIconStat("working", this.StatElement);
            scraper.execute();
            if(scraper.getStatus()==Scraper.STATUS_FINISHED){
                this.Succeed=true;
                Map<String,Object> tmp=new HashMap<String,Object>();
                tmp.put("UpdateTime", ((Variable) scraper.getContext().get("UpdateTime")).toString().trim());
                Buffer.setVal(this.Result);
                mainF.SetIconStat("done", this.StatElement);
            }else{
                this.Succeed=false;
                this.Result=null;
                Buffer.setVal(null);
                mainF.SetIconStat("error", this.StatElement);
            }
        }catch(Exception ex){
            this.Succeed=false;
            this.Result=null;
            Buffer.setVal(null);
            mainF.SetIconStat("error", this.StatElement);
        }
    }

    public void run() {
        this.extract();
    }    
}
4

3 に答える 3

5

shutdown() を shutdownNow() に変更すると、記述したコードで正しいことを実行しています。ただし、shutdownNow() のドキュメントを確認してください。

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

したがって、おそらく T1 と T2 は正しい方法でコーディングされておらず、割り込みに十分に応答していません。それらのコードをコピーできますか?

--

あなたのコードに基づいて、時間がかかるコードはscraper.execute()だと思いますよね?したがって、これらのメソッド内では、次のようなことを常に確認する必要があります。

if (Thread.interrupted()) {
   throw new InterruptedException();
}

割り込みが発生すると、InterruptedException がスローされて catch ステートメントでキャッチされ、スレッドが停止します。

于 2011-11-05T21:27:55.347 に答える
4

私の問題Future#cancel()は、その後の呼び出しget()CancellationException. エグゼキュータ サービスのシャットダウン後に部分的な結果を取得するためにget()、を呼び出すことができるようにしたい場合があります。Futureその場合、executor サービスに送信する callable に終了ロジックを実装できます。次のようなフィールドを使用します

private volatile boolean terminate;

public void terminate() {
    terminate = true;
}

必要に応じて呼び出し可能オブジェクトをチェックしterminateます。さらに、すべての callable を呼び出すことができるように、callable をどこかに覚えておく必要がterminate()あります。

于 2011-11-05T21:21:15.713 に答える
2

エグゼクターを使用します。submitFutureメソッドの場合、実行のキャンセルや完了の待機に使用できる を作成して返すことにより、基本メソッド Executor.execute(java.lang.Runnable) を拡張します。

task = Executor.submit( T1 )
...
task.cancel( true )
于 2011-11-05T21:17:11.343 に答える