有人认为Java 7的WatchService速度慢吗?

53

WatchService看起来是一个很棒的技术,但在我测试的OS X和Linux系统上它的速度太慢以至于无法使用。更加令人气馁的是,它似乎也无法通知所有事件。

这不仅适用于我的代码,也适用于Oracle的经典示例。(http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/essential/io/examples/WatchDir.java

我意识到OS X的OpenJDK端口对此功能不确定(参见https://wikis.oracle.com/display/OpenJDK/Mac+OS+X+Port+Project+Status

有没有人在生产环境中成功使用过它?


5
自2012年以来,这是一个非常令人烦恼的已知问题 - andruso
4
问题指出“OS X和Linux”,但答案和评论似乎表明这只是在OS X上的问题。 - Robert Tupelo-Schneck
2个回答

45

如果我进行改变,我的响应时间会更好。

folder.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);

folder.register(watcher, new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY}, SensitivityWatchEventModifier.HIGH);

1
需要注意的是,StandardWatchEventKinds枚举位于com.sun.*包中。 - eskatos
是的!这就是让我成功的原因,使用它之前我有4到5秒的延迟。参考我创建的脚本在这里:https://gist.github.com/DinisCruz-Dev/9214909 - Dinis Cruz
这将我的OS X上的延迟从10秒减少到2秒,但对于我的应用程序来说不够。也许我需要编写一个自定义轮询器(50-100毫秒的延迟将是足够的)。 - Esko Luontola
3
StandardWatchEventKinds现在是java.nio.file包的一部分,尽管SensitivityWatchEventModifier仍然属于Sun的私有包。 - asgs
2
@Paul 当然可以,但由于这是一个私有包,在不同的JVM实现(例如IBM的)之间不可移植。 - asgs
显示剩余3条评论

32

JDK 7 目前没有为 MacOS 提供 WatchService 的本地实现。相反,它使用后备的 sun.nio.fs.PollingWatchService,周期性地遍历文件系统并检查树中每个文件和子目录的最后修改时间戳,而非监听本机文件系统事件。我还发现它的速度极慢,无法使用。

这里有一个适用于 Mac 的原生 WatchService 实现:

http://code.google.com/p/barbarywatchservice/

我自己没有尝试过使用它。


8
在JDK 8的MacOS版本中,这种情况仍然存在吗? - Ben McCann
2
@ben,显然是的。由于速度非常慢且无法捕获所有事件,我们仍然存在问题。 - Johnny Everson
3
看起来JDK 9也无法解决这个问题。该问题仍然未解决,链接为https://bugs.openjdk.java.net/browse/JDK-7133447,并且在过去的邮件列表讨论中也没有得出解决方案:http://mail.openjdk.java.net/pipermail/nio-dev/2014-August/002691.html。 - Lari Hotari
2
警告!我们想使用BarbaryWatchService,但发现它在HighSierra上的APFS上表现不如预期。我已经在项目上提出了一个问题。问题链接 - Justin
4
Java 13现在有什么变化吗? - mjs
显示剩余4条评论

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