调度程序线程上的线程更新 GUI 会导致异常



我有 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)

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

WeakHashMap API 指定"如果在创建迭代器后的任何时间对映射进行结构修改,则除了通过迭代器自己的 remove() 方法之外,迭代器将抛出ConcurrentModificationException验证是否正在使用迭代器,如下所示。

您的程序也可能未正确同步。您可以使用 EventQueue.invokeLater() 更新事件调度线程上的 GUI,如下所示。