java - 使用监视文件夹重新启动线程

标签 java multithreading key watchservice

我有一个线程正在监视设置文件中设置的文件夹。如果我更改设置,我想停止线程并使用要观看的实际文件夹启动新线程。该代码运行“正常”,但收到一些错误消息。

public static void resetWatch() throws FileNotFoundException, IOException, InterruptedException {
    BufferedReader setup = new BufferedReader(new FileReader(new File("setup\\setup.dat")));
    String DirtoWatch = setup.readLine();

    Path toWatch = Paths.get(DirtoWatch);
    if(toWatch == null) {
        throw new UnsupportedOperationException("Directory not found");
    }

    // make a new watch service that we can register interest in
    // directories and files with.
    myWatcher = toWatch.getFileSystem().newWatchService();

    // start the file watcher thread below
    fileWatcher = new Watcher(myWatcher, toWatch);

    th = new Thread(fileWatcher, "FileWatcher");
    th.start();
    System.out.println("Monitoring " + DirtoWatch + " for changes...");
    // register a file
    toWatch.register(myWatcher, ENTRY_CREATE);
    th.join();
}

观察者类

public class Watcher implements Runnable {

    private WatchService myWatcher;
    public Path path;
    private WatchKey key;

    public Watcher(WatchService myWatcher, Path path) {
        this.myWatcher = myWatcher;
        this.path = path;
    }

    @Override
    public void run() {
        String evCon;

        try {
            // get the first event before looping
            key = myWatcher.take();
            while(key != null) {

                for (WatchEvent event : key.pollEvents()) {
                    evCon =  event.context().toString();
                    System.out.println("New file: " + evCon);
                    Thread.sleep(500);
                    folder_changed(path.toString() + "/" + evCon);
                }
                key.reset();
                key = myWatcher.take();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException ex) {
            Logger.getLogger(Watcher.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("Stopping thread");
    }

    public void stopThread() {
        try {
            System.out.println("Closing the ws");
            myWatcher.close();
            if(key!=null) {
                key.cancel();  
            }
            Thread.currentThread().interrupt();
        } catch (IOException | ClosedWatchServiceException exc) { System.out.println("Closing thread exception"); }
    }
}

如果我更改设置,我会更新设置文件,然后尝试关闭观察程序并再次运行线程:

try{
        fileWatcher.stopThread();
        myWatcher.close();
    }
    catch(ClosedWatchServiceException | IOException ex) { System.out.println("Watch Service exc. "); } 

    try {
        resetWatch();
    } catch (IOException | InterruptedException ex) { System.out.println("Recall resetWatch exc. "); }

然后它“正在运行”,但我得到了指向 watch 键的以下异常:

Monitoring ..path.. for changes...
Closing the ws
Monitoring ..path.. for changes...
Exception in thread "FileWatcher" java.nio.file.ClosedWatchServiceException
Recall resetWatch exc. 
    at sun.nio.fs.AbstractWatchService.checkOpen(AbstractWatchService.java:80)
    at sun.nio.fs.AbstractWatchService.checkKey(AbstractWatchService.java:92)
    at sun.nio.fs.AbstractWatchService.take(AbstractWatchService.java:119)
    at jstockcheck.Watcher.run(Watcher.java:40)
    at java.lang.Thread.run(Thread.java:748)

有什么建议可以避免这个错误吗?谢谢!

最佳答案

可以随时调用 close 方法来关闭服务,从而导致任何等待检索 key 的线程抛出 ClosedWatchServiceException

ClosedWatchServiceException - 如果此监视服务已关闭,或者在等待下一个键时关闭。

就你的情况而言,我认为,这只是在调用 take 时捕获异常并静默处理它的问题,例如:

try {
    key = myWatcher.take()
} catch (ClosedWatchServiceException e) {
    continue;
}

这是根据: https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html

关于java - 使用监视文件夹重新启动线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53460562/

相关文章:

java - 通过 REST API Java 从 URL 获取 ObjectID

java - 在本地主机上开发并在远程虚拟服务器上部署时的 Url 问题

java - Jackson Web Servlet 线程安全吗?

mysql - 在 MySQL 中使用 INDEX 和 KEY 有什么区别?

java - 测试 javax.swing.JButton 是否被按下

java - 我如何剖析或分析这个正则表达式?

c# - .NET 4.0 System.Collections.Concurrent 集合在 .NET 3.0 SynchronizedCollection 的功能中添加了什么?

c - C 中的套接字和线程

Qt:如何在子窗口的默认系统菜单中显示Ctrl+W而不是Ctrl+F4?

javascript - 尝试用 key 移动盒子,但不起作用