在WatchService中,key.pollEvents()和key.reset()之间会发生什么?

3

看一下这个Java示例,关于键状态,Oracle表示:

Ready 表示该键准备好接受事件。创建时,键处于就绪状态。

Signaled 表示有一个或多个事件已排队。一旦键被信号标记,直到调用重置方法之前,它将不再处于就绪状态。

WatchKey javadoc中:

当键处于信号状态时检测到的事件会排队,但不会导致键重新排队以从监视服务中检索

文档没有说明在key.pollEvents()key.reset()之间生成的事件会发生什么?假定事件将被缓冲,直到键被重置,并且键将立即在重置后被标记。这似乎得到了以下测试的支持。

请问您能否指向一些官方文档?或者有关缺乏文档的讨论?
Path dir = Paths.get("test");
WatchService watcher = dir.getFileSystem().newWatchService();
dir.register(watcher, CREATE, DELETE, MODIFY);
while (true) {
    WatchKey key = watcher.take();
    System.out.println("polling.");
    for (WatchEvent<?> event : key.pollEvents()) {
        ... (details removed) ...
        System.out.format("  Event %s in [%s] for entry [%s]%n",
                          event.kind().name(), registeredDir, childPath);
        try { Thread.sleep(20000); } catch (InterruptedException e) { ; }
    }
    System.out.println("resetting.");
    key.reset();
}

sleep()允许的20秒内,我做了以下操作:

  • 创建文件,
  • 编辑它并保存,
  • 重命名它,
  • 再次编辑并保存,
  • 删除它。

输出结果:

polling.
  Event ENTRY_CREATE in [test] for entry [test\file1.txt]
resetting.
polling.
  Event ENTRY_MODIFY in [test] for entry [test\file1.txt]
  Event ENTRY_DELETE in [test] for entry [test\file1.txt]
  Event ENTRY_CREATE in [test] for entry [test\file2.txt]
  Event ENTRY_MODIFY in [test] for entry [test\file2.txt]
  Event ENTRY_DELETE in [test] for entry [test\file2.txt]
resetting.

谢谢。

1个回答

0

看起来有额外的事件被缓存并将在缓冲区填满时被处理或赋予溢出事件类型。

来自watchservice文档:

“文件系统可能会比它们被检索或处理得更快地报告事件,实现可能对其累积的事件数量施加未指定的限制。如果实现知道丢弃事件,则安排键的pollEvents方法返回一个具有溢出事件类型的元素。此事件可以由消费者用作重新检查对象状态的触发器。”


你有参考资料来证实这个可能性吗? - mins
@mins 我只是在浏览 http://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html ,我还没有进行测试。 - pwilmot
我编辑了我的问题以展示一些我所做的测试,但没有触发OVERFLOW。似乎事件被缓冲并在键重置后立即可用。但我找不到任何确认。 - mins
@mins 这是一个测试套件示例,用于引发OVERFLOW。https://github.com/AdoptOpenJDK/openjdk-jdk9u/blob/master/jdk/test/java/nio/file/WatchService/LotsOfEvents.java - DanielCuadra

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