【问题标题】:Thread updating GUI on dispatcher thread causes exception调度程序线程上的线程更新 GUI 导致异常
【发布时间】:2014-10-08 16:21:59
【问题描述】:

我有 2 个线程,一个是为我的应用程序运行“服务器”的线程,另一个是 GUI 的事件调度程序,如图所示:

    public static void main(String[] args) 
    {
    //Connections
    Runnable r2 = new Runnable() {
        @Override
        public void run() 
        {
            App.connectToServer();
        }
    };


    //Launch main window
    SwingUtilities.invokeLater(new Runnable() {
        public void run() 
        {
            //Installs theme
            WebLookAndFeel.install();

            //Launches main window
            BootWindow myMainWindow = new BootWindow();
        }
    });

    Thread thr2 = new Thread(r2);
    thr2.start();
}

//Get instance
public static App getInstance()
{
    if ( instance == null )
    {
        // Creating window instance
        instance = new App();
    }
    return instance;
}

//Server connections
private static void connectToServer()
{
    System.out.println("Connecting to the eTrade Manager Server..");
    etmServer server = new etmServer();
    server.connectEtmServer();

}

在应用程序的服务器线程中,有一个方法可以侦听来自服务器的新消息,然后该方法调用 GUI 线程中的类中的 updateStatus 方法并尝试更新面板的背景颜色:

正在监听的方法:

@Override
public void ProcessSystemStatus(SystemStatusUpdateWrapper systemUpdate) 
{
    System.out.println("----System Update----");
    System.out.println("Connection ID: " + systemUpdate.getConnectionId());
    System.out.println("System Status: " + systemUpdate.getSystemStatus());
    System.out.println("Risk State: " + systemUpdate.getRiskState());
    System.out.println("---------End---------");

    Summary smryWindow = new Summary();
    smryWindow.updateStatus("Qtime", systemUpdate.getSystemStatus());
}

GUI 线程中的更新方法

public void updateStatus(String panelName, String status)
{
    if(panelName == "Qtime")
    {
        if(status == "ENABLED")
        {
            qtimeStatusPanel.setBackground(Color.GREEN);

            try
            {
                qtimeStatusPanel.validate();
                qtimeStatusPanel.repaint();
            }
            catch (Exception ex)
            {
                System.err.println(ex.getMessage());
            }
        }
        else
        {
            qtimeStatusPanel.setBackground(Color.RED);
        }

    }
}

当 updateStatus 被调用时,它会抛出一个异常:

java.util.ConcurrentModificationException
at java.util.WeakHashMap$HashIterator.nextEntry(WeakHashMap.java:762)
at java.util.WeakHashMap$EntryIterator.next(WeakHashMap.java:801)
at java.util.WeakHashMap$EntryIterator.next(WeakHashMap.java:799)
at com.alee.managers.style.StyleManager.applySkin(StyleManager.java:300)

我不知道如何处理这个问题,有什么建议吗?

【问题讨论】:

  • 您的 ProcessSystemStatus 方法似乎被 EDT 以外的某个线程调用,但是如果没有行号或完整的代码集,就很难判断。 ProcessSystemStatus 最终会在调用App.connectToServer() 期间被调用吗?
  • "在 GUI 线程中的类中" 这对我来说似乎没有意义。您在 GUI 线程中,或者您不在。它是什么类甚至对象没有任何区别。
  • 是的 ProcessSystemStatus 在 App.connectToServer() @BenLawry 期间被调用
  • 应用服务器在不同的线程上,我的最终目标是当 ProcessSystemStatus 调用 updateStatus 并且它们都在不同的线程上运行时更新 GUI @TomHawtin-tackline
  • 不要使用"==" 来比较字符串。使用equals(...) 方法。

标签: java multithreading swing


【解决方案1】:

WeakHashMap API 规定“如果在迭代器创建后的任何时候对映射进行结构修改,以任何方式除了通过迭代器自己的remove() 方法,迭代器将抛出a ConcurrentModificationException." 验证您使用的是迭代器,如图所示here

您的程序也可能未正确同步。您可以使用EventQueue.invokeLater() 更新event dispatch thread 上的GUI,如图here

【讨论】:

    猜你喜欢
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 2013-05-22
    相关资源
    最近更新 更多