调度程序线程上的线程更新GUI导致异常 [英] Thread updating GUI on dispatcher thread causes exception

查看:105
本文介绍了调度程序线程上的线程更新GUI导致异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个线程,一个是为我的应用程序运行服务器"的线程,另一个是GUI的事件分派器,如下所示:

I have 2 threads, one is a thread that runs the "server" for my app, and the other is the event dispatcher for the GUI as shown:

    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方法,并尝试更新面板的背景色:

In the app's server thread there's a method that listens to new messages that come from a server, this method then calls the updateStatus method in a class that's in the GUI's thread and tries to update a panel's background color:

正在监听的方法:

@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时会引发异常:

When the updateStatus gets called it throws an exception:

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)

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

I'm not sure how to handle this, any advice?

推荐答案

WeakHashMap API指定如果在创建迭代器之后的任何时间对地图进行结构修改,则通过迭代器自己的remove()以任何方式 方法,迭代器将抛出ConcurrentModificationException."确认您正在使用迭代器,如这里.

The WeakHashMap API specifies that "if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove() method, the iterator will throw a ConcurrentModificationException." Verify that you are using the iterator, as shown here.

您的程序也可能不正确地同步.您可以使用 EventQueue.invokeLater() ,如此处所示.

Your program may also be incorrectly synchronized. You can update the GUI on the event dispatch thread using EventQueue.invokeLater(), as shown here.

这篇关于调度程序线程上的线程更新GUI导致异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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