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 位操作系统和 1.5 - 7.0 的 java 版本中

问题描述:在同时运行两个线程时,第一个线程使用 Thread.interrupt() 中断第二个线程。第二个线程测试它是否已被中断调用 Thread.isInterrupted() 方法,该方法总是返回 false。

这发生在运行 64 位操作系统(Vista 和 Linux)的多处理器 PC 上。在 Vista 64 位上,当使用 64 位 JVM(从 1.5 到 1.7 的所有版本)时会发生这种情况,但在使用 32 位 JVM 时不会发生。在 64 位 Linux 上,当使用 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() 没有的事实有关。它有时对杰罗姆有用,对我总是有用,对你从来没有(?)可能表明我们正在使用的 jdks 或我们机器的速度存在差异。如果它与清除状态有关,那可能解释了可变性。

于 2010-01-06T12:19:04.577 回答