5

TaskExecutor によって返される Futures オブジェクトのリストを管理したいと考えています。
私はこのようなものを持っています

 List<Future<String>> list 

 void process(ProcessThis processThis) {     
    for ( ...) {
       Future<String> future = taskExecutor.submit(processThis);
       list.add(future)
    }
 }


 void removeFutures() {
    for(Future future : list) {
       assert future.cancel(true);
 }

ProcessThis は Callable< String> を実装し、Thread.interrupted() ステータスをチェックするタスクです。

    public String call() {
        while (true) {
            if (Thread.interrupted()) {
                break;
            }
            doSomething();
        }
    }

ここでの問題は、Thread.interrupted() が呼び出されたときに、並行スレッドのサブセットのみが「true」を返すことです。
removeFutures() の assert は、削除されるすべてのフューチャに対して true を返します (isDone() と isCompleted() もチェックしました。
中断されるスレッドの数はランダムです。実行中のスレッドが 15 を超えると、13 が中断されることもあれば、2 .. .
どこに問題があるのか​​本当にわかりません. future.cancel(true) を呼び出して true が返された場合...そして Thread.interrupted をチェックすると (これは 1 回だけ呼び出されます)、これも true を返すと予想されます
何が欠けているのか分かりませんか?私

はビルド Java 1.6.0_02-b05 を使用しています

4

3 に答える 3

6

Thread.interrupted()は現在の中断ステータスを返し、それをクリアすることに注意してください。したがって、今後のすべての呼び出しは false を返します。あなたが望むのはおそらくThread.currentThread().isInterrupted().

future.cancel(true)また、タスクがすでに完了しているかキャンセルされている場合、 は通常 false のみを返すことに注意してください。true が返されたとしても、タスクが実際にキャンセルされるという保証はありません。

で何が起こっていdoSomething()ますか? 割り込みが原因で、RuntimeException がどこかにエスケープしている可能性があります。UncaughtExceptionHandlerが設定されていますか? そうでない場合は、ThreadFactoryをに渡してExecutor、例外ハンドラーを設定し、見逃した例外をログに記録する必要があります。

于 2010-01-21T13:52:45.983 に答える
2

割り込みがしばしば飲み込まれる潜在的な問題。そのため、どこか深いところでdoSomething()(またはクラスのロードでさえ)、割り込みがキャッチされ、たとえばwait()「不注意な」コードによって破棄される可能性があります。割り込みは悪です、IMO。

キャンセル時にすべてのタスクが実際に実行されていることを確認する価値があるかもしれません。

于 2010-01-21T13:45:13.360 に答える
2

少なくとも、割り込みフラグを復元して、taskExecutor にスレッドの割り込みを認識させる必要があります。

public String call() { 
    while (true) { 
        if (Thread.interrupted()) { 
            Thread.currentThread().interrupt();
            break; 
        } 
        doSomething(); 
    } 
} 
于 2010-01-21T12:59:20.733 に答える