Java 在jdk7监视服务API中,何时抛出溢出事件?

Java 在jdk7监视服务API中,何时抛出溢出事件?,java,io,java-7,nio2,Java,Io,Java 7,Nio2,各国: 溢出–表示事件可能已丢失或丢弃 它并没有说在什么情况下我应该期望事件丢失或丢弃?起初,我认为这是由于将大量文件快速写入文件夹的结果。我创建了几千个大小为零的文件,并将它们移动到一个受监控的目录中。没有溢出 我错过了什么 “文件系统报告事件的速度可能快于检索或删除事件的速度 已处理,而实现可能会对 它可能累积的事件数。其中 故意丢弃事件,然后安排密钥的轮询事件 方法返回事件类型为溢出的元素。此事件 消费者可以将其用作重新检查状态的触发器 对象。” 从 另见Steven C的答案。我认为,他

各国:

溢出–表示事件可能已丢失或丢弃

它并没有说在什么情况下我应该期望事件丢失或丢弃?起初,我认为这是由于将大量文件快速写入文件夹的结果。我创建了几千个大小为零的文件,并将它们移动到一个受监控的目录中。没有溢出

我错过了什么


“文件系统报告事件的速度可能快于检索或删除事件的速度 已处理,而实现可能会对 它可能累积的事件数。其中 故意丢弃事件,然后安排密钥的轮询事件 方法返回事件类型为溢出的元素。此事件 消费者可以将其用作重新检查状态的触发器 对象。”

另见Steven C的答案。我认为,他关于未消费事件的观点起了作用

我创建了几千个大小为零的文件,并将它们移动到一个受监控的目录中。没有溢出


您大概是在创建事件的同时消费这些事件。如果要触发溢出,请尝试暂停事件的使用,生成大量事件(如上所述),然后恢复使用。操作系统可以缓冲的未使用事件的数量必然有限制。

产生溢出的最小示例

只需在
watcherService.register之后和
watcherService.take之前创建文件

调用:

java Overflow 256
控制事件的数量

Java7和Ubuntu14.04在512个事件中达到最大值

每次出现溢出时,
pollEvents()
只返回一个事件,但Javadoc中没有明确指定

考虑到以下情况,我觉得这一限制如此之小很奇怪:

  • my
    sysctl fs.inotify.max_user_watches
    524288
  • JDK似乎在Linux上使用了
    inotify
守则:

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchService;
import java.util.List;

public class Overflow {

    @SuppressWarnings("unchecked")
    static <T> WatchEvent<T> cast(WatchEvent<?> event) {
        return (WatchEvent<T>)event;
    }

    public static void main(final String[] args) throws InterruptedException, IOException {
        int nfiles;
        if (args.length > 0)
            nfiles = Integer.parseInt(args[0]);
        else
            nfiles = 10_000;
        Path directory = Files.createTempDirectory("watch-service-overflow");
        final WatchService watchService = FileSystems.getDefault().newWatchService();
        directory.register(
                watchService,
                StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE);
        final Path p = directory.resolve(Paths.get("Hello World!"));
        for (int i = 0; i < nfiles; i++) {
            Files.createFile(p);
            Files.delete(p);
        }
        List<WatchEvent<?>> events = watchService.take().pollEvents();
        for (final WatchEvent<?> event : events) {
            if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
                System.out.println("Overflow.");
                System.out.println("Number of events: " + events.size());
                return;
            }
        }
        System.out.println("No overflow.");
        Files.delete(directory);
    }
}
导入java.io.File;
导入java.io.IOException;
导入java.nio.file.FileSystems;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.nio.file.path;
导入java.nio.file.StandardWatchEventTypes;
导入java.nio.file.WatchEvent;
导入java.nio.file.WatchService;
导入java.util.List;
公共类溢出{
@抑制警告(“未选中”)
静态WatchEvent强制转换(WatchEvent事件){
返回(WatchEvent)事件;
}
公共静态void main(最终字符串[]args)引发InterruptedException,IOException{
内部文件;
如果(args.length>0)
nfiles=Integer.parseInt(args[0]);
其他的
n文件=10_000;
Path directory=Files.createTempDirectory(“监视服务溢出”);
final WatchService WatchService=FileSystems.getDefault().newWatchService();
目录.寄存器(
值班服务,
StandardWatchEventTypes.ENTRY\u创建,
StandardWatchEventTypes.ENTRY\u DELETE);
最终路径p=directory.resolve(Path.get(“helloworld!”);
对于(int i=0;i列表"文件系统报告事件的速度可能快于检索或处理事件的速度,而实现可能会对其可能累积的事件数施加未指定的限制。如果实现故意丢弃事件,则会安排键的pollEvents方法返回事件类型为溢出的元素。此事件可以是消费者将其用作重新检查对象状态的触发器。“从。可能您没有施加足够的负载来创建溢出。@Fildor,谢谢。我忘记阅读此JavaDoc。请作为答案发布,以便我可以接受它。