9

次のプログラムは、問題を示しています (最新の JVM など)。

public static void main(String[] args) throws InterruptedException {
    // if this is true, both interrupted and isInterrupted work
    final boolean withPrint = false;

    // decide whether to use isInterrupted or interrupted.
    // if this is true, the program never terminates.
    final boolean useIsInterrupted = true;

    ExecutorService executor = Executors.newSingleThreadExecutor();
    final CountDownLatch latch = new CountDownLatch(1);
    Callable<Void> callable = new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            Random random = new Random();
            while (true) {
                if (withPrint) {
                    System.out.println(random.nextInt());
                    System.out.flush();
                }
                if (useIsInterrupted)
                {
                    if (Thread.currentThread().isInterrupted())
                        break;
                }
                else
                {
                    if (Thread.interrupted())
                        break;
                }
            }
            System.out.println("Nice shutdown");
            latch.countDown();
            return null;
        }
    };
    System.out.println("Task submitted");
    Future<Void> task = executor.submit(callable);
    Thread.sleep(100);
    task.cancel(true);
    latch.await();
    System.out.println("Main exited");
    executor.shutdown();
}
4

2 に答える 2

5

これは、主に 64 ビット OS および Java バージョン 1.5 ~ 7.0 のマルチプロセッサ マシンの既知の問題のようです。

問題の説明 : 2 つのスレッドを同時に実行しているときに、最初のスレッドが Thread.interrupt() を使用して 2 番目のスレッドに割り込みます。2 番目のスレッドは、常に false を返す Thread.isInterrupted() メソッドの呼び出しが中断されたかどうかをテストします。

これは、64 ビット OS (Vista および Linux) を実行しているマルチプロセッサ PC で発生します。Vista 64 ビットでは、これは 64 ビット JVM (1.5 から 1.7 までのすべてのバージョン) を使用すると発生しますが、32 ビット JVM を使用すると発生しません。Linux 64 ビットでは、これは 64 ビット JVM (1.5 から 1.7 までのすべてのバージョン) または 32 ビット JVM (1.5 から 1.7 までのすべてのバージョン) を使用する場合に発生します。

解決策は、修正されたバージョン (1.6.0_16-b02 以降) をインストールすることです。

于 2010-01-06T12:34:17.360 に答える
0

ripper234、私は自分のマシンでこれを実行したところ、印刷に使用する値や使用する割り込みに関係なく、常に停止します。jdk1.6.0_16 を使用しています。javadoc を見ると、interrupted() が各呼び出しの後に (中断された) 状態をクリアし、isInterrupted() がクリアしないという事実に関係している可能性があります。ジェロームでは時々機能し、私では常に機能し、あなたにとってはまったく(?)機能しないという事実は、使用しているjdkまたはマシンの速度の違いを示している可能性があります。それが状態のクリアと関係がある場合、それは変動性を説明するかもしれません.

于 2010-01-06T12:19:04.577 に答える