jdk7 watch service API中,啥时候会抛出OVERFLOW事件?

Posted

技术标签:

【中文标题】jdk7 watch service API中,啥时候会抛出OVERFLOW事件?【英文标题】:In jdk7 watch service API, when will the OVERFLOW event be thrown?jdk7 watch service API中,什么时候会抛出OVERFLOW事件? 【发布时间】:2013-09-06 07:44:32 【问题描述】:

documentation for the overflow 声明:

OVERFLOW – 表示事件可能已丢失或丢弃。

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

我错过了什么?

【问题讨论】:

"文件系统报告事件的速度可能比它们被检索或处理的速度更快,并且实现可能会对它可能累积的事件数量施加未指定的限制。如果实现故意丢弃事件,那么它会安排键的 pollEvents 方法返回事件类型为 OVERFLOW 的元素。消费者可以使用此事件作为触发器来重新检查对象的状态。来自JavaDoc。也许您没有施加足够的负载来造成溢出。 @Fildor,谢谢。我忘了阅读这个 JavaDoc。请作为答案发布,以便我接受。 【参考方案1】:

产生溢出的最小示例

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

调用:

java Overflow 256

控制事件的数量。

Java 7 和 Ubuntu 14.04 最多支持 512 个事件。

每次发生溢出时,pollEvents() 只返回一个事件,但这在 Javadoc 上并没有明确规定。

考虑到这个限制如此之小,我觉得很奇怪:

我的sysctl fs.inotify.max_user_watches524288 https://unix.stackexchange.com/questions/13751/kernel-inotify-watch-limit-reached JDK 似乎在 Linux 上使用 inotify:http://hg.openjdk.java.net/jdk7u/jdk7u60/jdk/file/33c1eee28403/src/solaris/native/sun/nio/fs/LinuxWatchService.c#l36

代码:

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);
    

【讨论】:

【参考方案2】:

“文件系统报告事件的速度可能快于它们被检索或 处理和实施可能会施加一个未指定的限制 它可能累积的事件数。在哪里实施 故意丢弃事件,然后安排键的 pollEvents 方法返回事件类型为 OVERFLOW 的元素。这个事件 消费者可以将其用作重新检查状态的触发器 对象。”

来自JavaDoc。

另请参阅 Steven C 的回答。我认为他关于未消费事件的观点有所不同。

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于jdk7 watch service API中,啥时候会抛出OVERFLOW事件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Service Worker Cache API 和常规浏览器缓存有啥区别?

在 Azure Service Fabric 中,无状态 Web API 和 ASP.NET Core Web API 之间有啥区别?

API(网关)提供的反向代理和Service Fabric有啥区别?

Java Servlet:Servlet接口service工作(ServletRequest,ServletResponse对象)(jdk7+tomcat7+eclipse)

vue.js中,啥时候用methods?啥时候用computed?啥时候用watch?

angular中的路由,watch,service和ajax