6

ExecutorServiceRunnable タスクをフィードする がある場合、1 つを選択して中断できますか?
返された Future をキャンセルできることはわかっています (ここにも記載されています: how-to-interrupt-executors-thread ) InterruptedException。キャンセルはそれを行うようには見えません (ソースを見ることでイベントが発生するはずですが、OSX の実装が異なる可能性があります)。少なくとも、このスニペットは「それ!」を出力しません。たぶん私は何かを誤解しており、例外を受け取るのはカスタムランナブルではありませんか?

public class ITTest {
static class Sth {
    public void useless() throws InterruptedException {
            Thread.sleep(3000);
    }
}

static class Runner implements Runnable {
    Sth f;
    public Runner(Sth f) {
        super();
        this.f = f;
    }
    @Override
    public void run() {
        try {
            f.useless();
        } catch (InterruptedException e) {
            System.out.println("it!");
        }
    }
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
    ExecutorService es = Executors.newCachedThreadPool();
    Sth f = new Sth();
    Future<?> lo = es.submit(new Runner(f));
    lo.cancel(true); 
    es.shutdown();
}

}

4

1 に答える 1

11

ここで行うべき正しいことは、をキャンセルすることFutureです。問題は、これが必ずしもInterruptedException.

ジョブがまだ実行されていない場合は、実行可能なキューから削除されます。これが問題だと思います。ジョブがすでに終了している場合は、何もしません (もちろん)。まだ実行中の場合は、スレッドを中断します

スレッドを中断すると、、、およびその他のメソッドがスローされるsleep()だけwait()ですInterruptedException。スレッドが次のように中断されているかどうかを確認するためのテストも必要です。

if (Thread.currentThread().isInterrupted()) {

また、キャッチした場合に割り込みフラグをリセットするのも良いパターンですInterruptedException:

try {
   Thread.sleep(1000);
} catch (InterruptedException e) {
   // this is a good pattern otherwise the interrupt bit is cleared by the catch
   Thread.currentThread().interrupt();
   ...
}

あなたのコードでは、あなたが呼び出す前にlo.cancel(true)スリープさせてみます。実行する機会を得るに、未来をキャンセルしている可能性があります。

于 2012-08-21T17:50:51.483 に答える