如何在Java 8桌面应用程序中替换或重新启动死锁的Swing EventDispatchThread/EventQueue [英] How to replace or restart a deadlocked Swing EventDispatchThread/EventQueue in Java 8 desktop application

查看:132
本文介绍了如何在Java 8桌面应用程序中替换或重新启动死锁的Swing EventDispatchThread/EventQueue的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前一段时间,我们向应用程序中添加了一些代码以检测并尝试从Swing EDT死锁中恢复,因此用户至少可以保存他们的文件(最好没有死锁,但是...) .在Java 1.6中,这很容易.检测到EDT已被阻止足够长的时间,然后从后台线程调用此方法:

A while back we added some code to our application to detect and attempt to recover from a Swing EDT deadlock, so the user could at least save their files (it would be best to not have a deadlock, but...). In Java 1.6, this is easy. Detect that the EDT has been blocked for a sufficient amount of time, and then call this from a background thread:

EventQueue newQ = new EventQueue();
Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQ);

新的UI事件将在新的EventQueue/EDT上处理,用户可以保存其工作.

New UI events will be processed on a new EventQueue/EDT, and the user can save their work.

在Java 8中,此操作无效,因为EventQueue.push的实现已更改为将(已阻止的)EventDispatchThread从旧队列复制到新队列.

In Java 8, this does not work because the implementation of EventQueue.push has been changed to copy the (blocked) EventDispatchThread from the old queue to a new one.

推荐答案

当然,我总能做些小事:

Of course, I can always do something a little evil:

private static void hackAroundJava8Protections(EventQueue newQ) {
    try {
        Field field = newQ.getClass().getDeclaredField("dispatchThread");
        field.setAccessible(true);
        field.set(newQ, null);
        Method method = newQ.getClass().getDeclaredMethod("initDispatchThread");
        method.setAccessible(true);
        method.invoke(newQ);
    } catch (Throwable e) {
        throw new RuntimeException(e);
    }
}

这将启动一个新的EventDispatchThread,从而允许使用应用程序UI.我能够像保存用户一样保存数据.我不确定可能会有什么弊端.也许有一种不太可怕的方法来重新启动被阻止的EDT?

This starts a new EventDispatchThread, allowing use of the application UI. I was able to save data as if I were a user. I'm not sure of what downsides there might be. Maybe there's a less scary way of restarting a blocked EDT?

这篇关于如何在Java 8桌面应用程序中替换或重新启动死锁的Swing EventDispatchThread/EventQueue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆