线程中断状态被清除 - 可能是Java错误

Jat*_*tin 8 java concurrency multithreading interrupt

这是参考Path#register方法.如果一个线程正在运行一个包含该方法的块,另一个线程会事先中断它.然后发现该方法清除了中断状态.

在文档中没有提到它清除了线程的中断状态.

要复制

import java.io.*;
import java.nio.file.*;
import static java.nio.file.LinkOption.*;
import static java.nio.file.StandardWatchEventKinds.*;
import java.nio.file.attribute.*;


public class WatchDir {

private final WatchService watcher;


private void register(Path dir) throws IOException {
    //interrupt itself
    Thread.currentThread().interrupt();
    boolean before = Thread.currentThread().isInterrupted();
    WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
    boolean after = Thread.currentThread().isInterrupted();

    if(before){
        if(!after){
            System.out.println("--------------------BUG-------------------");
            System.out.format("Interrupt Status: true before making call to Path#register for folder folder: %s\n", dir);
            System.out.format("Interrupt Status: false after making call to Path#register for folder folder: %s\n", dir);
            System.out.println("The interrupt status was cleared by `register` (Unexpected Behavior).");
            System.exit(0);
        }else{
            System.out.println("Not a bug on your machine. The interrupt was not cleared after call to Path#register. Works as expected");
            System.out.println("Works well on your machine. Didn't work for me on Windows and Ubuntu with Java 7");
        }
    }
}

/**
 * Creates a WatchService and registers the given directory
 */
WatchDir(Path dir) throws IOException {
    this.watcher = FileSystems.getDefault().newWatchService();
    register(dir);
}


public static void main(String[] args) throws Exception {
    // register directory and process its events
    Path dir = Paths.get(".");
    new WatchDir(dir);
}}
Run Code Online (Sandbox Code Playgroud)

在上面你可以看到调用register函数后中断状态被清除.样本输出:

--------------------BUG-------------------
Interrupt Status: true before making call to Path#register for folder folder: .
Interrupt Status: false after making call to Path#register for folder folder: .
The interrupt status was cleared by `register` (Unexpected Behavior).
Run Code Online (Sandbox Code Playgroud)

出现此问题是因为即使在请求关闭后,仍发现服务仍处于活动状态.有任何想法吗?

编辑:事实证明它只发生在Windows和Linux中.Mac的行为符合预期.我的操作系统:赢得7位64位.JDK 1.7.0_11.另请参见:Ubuntu 14.04 Java 1.7.0_45-b18

Bor*_*vić -1

问题可能出在catch块上:

} catch (InterruptedException ex) {
  Logger.getLogger(WatchDir.class.getName()).log(Level.SEVERE, null, ex);
}
Run Code Online (Sandbox Code Playgroud)

尝试添加

// Restore the interrupted status
Thread.currentThread().interrupt();
Run Code Online (Sandbox Code Playgroud)

catch街区里。

有关此主题的更多信息,请参阅“Java 理论与实践:处理 InterruptedException”一文

  • @BorisPavlović 代码确实吞下了(忽略)InterruptedException - 请参阅我在上面的评论中发布的链接。 (2认同)