java - 导致故障转储的 Java 错误的解决方法

标签 java windows multithreading nio crash-dumps

由于这个错误,我开发的一个程序偶尔会导致 JVM 崩溃:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8029516 .不幸的是,Oracle 还没有解决这个错误,错误报告说没有已知的解决方法。

我试图通过在 KeyWatcher 线程中调用 .register(sWatchService, eventKinds) 来修改错误报告中的示例代码,方法是将所有待处理的注册请求添加到我在 KeyWatcher 线程中循环的列表,但它是还在崩溃。我猜这与在 sWatchService 上同步具有相同的效果(就像错误报告的提交者所尝试的那样)。

你能想出什么办法来解决这个问题吗?

最佳答案

来自评论:

It appears that we have an issue with I/O cancellation when there is a pending ReadDirectoryChangesW outstanding.

声明和示例代码表明错误在以下情况下触发:

  1. 有一个未被消费的未决事件(它可能对 WatchService.poll()WatchService.take() 可见,也可能不可见)<
  2. WatchKey.cancel() 在键上调用

这是一个没有通用解决方法的严重错误。该方法取决于您的应用程序的具体情况。考虑将 watch 集中到一个地方,这样您就不需要调用 WatchKey.cancel()。如果某一时刻池变得太大,请关闭整个 WatchService 并重新开始。类似于。

public class FileWatcerService {
    static Kind<?>[] allEvents = new Kind<?>[] {
        StandardWatchEventKinds.ENTRY_CREATE,
        StandardWatchEventKinds.ENTRY_DELETE,
        StandardWatchEventKinds.ENTRY_MODIFY
    };

    WatchService ws;

    // Keep track of paths and registered listeners
    Map<String, List<FileChangeListener>> listeners = new ConcurrentHashMap<String, List<FileChangeListener>>();
    Map<WatchKey, String> keys = new ConcurrentHashMap<WatchKey, String>();

    boolean toStop = false;

    public interface FileChangeListener {
        void onChange();
    }

    public void addFileChangeListener(String path, FileChangeListener l) {
        if(!listeners.containsKey(path)) {
            listeners.put(path, new ArrayList<FileChangeListener>());
            keys.put(Paths.get(path).register(ws, allEvents), path);
        }
        listeners.get(path).add(l);
    }

    public void removeFileChangeListener(String path, FileChangeListener l) {
        if(listeners.containsKey(path))
            listeners.get(path).remove(l);
    }

    public void start() {
        ws = FileSystems.getDefault().newWatchService();
        new Thread(new Runnable() {
            public void run() {
                while(!toStop) {
                    WatchKey key = ws.take();
                    for(FileChangeListener l: listeners.get(keys.get(key)))
                        l.onChange();
                }
            }
        }).start();
    }

    public void stop() {
        toStop = true;
        ws.close();
    }
}

关于java - 导致故障转储的 Java 错误的解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23298187/

相关文章:

ruby 事件机器 + AMQP : Ensuring specific async calls happen before raising exceptions

java - 对 ArrayList 起作用的两种方法的同步

java - 如何用Java找到某个文件的位置?例如- 图片、文档、下载

c++ - 客户端程序中的 glewInit() 和 GLEW_ARB_xxx_ 失败

java - 使用 servlet jsp 在 Windows 中将 Hbase 作为 DB 运行

python - Windows 上的无服务器部署

用于多个相同任务的 Java 线程池

java - 更新 Jlabel 的新位置

java - 使用Java下载文件

java - 我是在创建对象还是变量?