Thread.isInterrupted方法无效,应该使用Thread.interrupted方法。

10
以下程序演示了问题(最新的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();
}

它并不总是无法停止。 - Jerome
Jerome,请检查你的编译器设置...也许你正在使用早期的JVM。 - PaulP1975
2个回答

5
这似乎是多处理器机器上的已知问题,主要出现在64位操作系统和Java 1.5-7.0版本中。
问题描述: 在运行两个同时线程时,第一个线程使用Thread.interrupt()中断第二个线程。 第二个线程调用Thread.isInterrupted()方法测试是否被中断,但始终返回false。
这种情况发生在运行64位操作系统(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或更高版本。

不错的发现,但是这个 bug 的状态是“已解决,修复于 hs16(b04) 版本”。这是我正在运行的版本:java version "1.6.0_14" Java(TM) SE Runtime Environment (build 1.6.0_14-b08) Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode) - ripper234
也许我只是不理解Java版本号。这个错误是否应该在我拥有的JDK中得到修复?我应该重新打开它还是下载新的JDK? - ripper234
hs16(b04)是热点版本,而不是JRE版本。看起来修复程序在1.6.0_16-b02中,该版本比您的版本更新,因此您应该下载最新版本(1.6.0_17)。 - Mocky
1
我改用AtomicBoolean来通知线程,而不是中断线程。还没有检查更新JVM是否解决了这个问题。 - ripper234

0
ripper234,我刚在我的电脑上运行了这个程序,无论我使用哪个打印值和中断,它总是停止。我正在使用jdk1.6.0_16。看着javadoc,也许与interrupted()在每次调用后清除(中断)状态而isInterrupted()不清除有关。对于jerome有时可以工作,对于我总是可以工作,而对于你从来没有(?),可能表明我们使用的jdk或我们机器的速度存在差异。如果与状态的清除有关,那可能可以解释这种变化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接