gpt4 book ai didi

java - 解决 Swingworker 应用程序中的并发修改异常

转载 作者:行者123 更新时间:2023-12-02 07:30:24 25 4
gpt4 key购买 nike

我正在编写一个应用程序,其中在 SwingWorker 中运行一些模拟。在此模拟中,某些集保留在 SwingWorker 的 doInBackground() 方法中修改的数据。这些数据需要由 GUI 显示,但显然这会失败,因为只要 GUI 开始访问这些集,就会抛出并发修改异常,因为 SwingWorker 正在修改相同的集。

如何在 SwingWorker 不必等待 GUI 完成数据绘制的情况下共享此数据?我是否必须复制数据然后发布()这些数据?这样不是会增加很多数据量(数据很多)吗?还有其他方法可以解决这个问题吗?

这是一些简化的代码:

public class World {
public Set<Foo> fooSet = new HashSet<Foo>();
}

public class Simulator extends SwingWorker<Void, Void> {
private World world;
private WorldPanel worldPanel;

public Simulator(World world, WorldPanel worldPanel) {
this.world = world;
this.worldPanel = worldPanel;
}

@Override
protected Void doInBackground() throws Exception {
while (true) {
doSomethingWithFooSet() //structurally modifies the set
publish();
}
}

@Override
protected void process(List<Void> voidList) {
worldPanel.repaint();
}
}

public class WorldPanel extends JPanel {
private final World world;

public WorldPanel(World world) {
this.world = world;
}

@Override
public void paintComponent(Graphics g) {
drawWorld() //reads from fooSet in world
}
}

不要误会我的意思,我明白为什么这不起作用,我只是想知道我应该在这个设计中改变什么才能做到我想做的事情:访问与我的模拟相同的数据修改。 process() 是否在 EDT 上运行?如果是这样,是否可以让 process() 更新 WorldPanel 用于绘制数据的世界对象副本中的集合?

最佳答案

您无法同时更新和显示世界对象,因此您有两种方法:依次更新和显示,或者克隆数据,使更新和显示的数据不同。要实现第一个变体,只需不要使用 SwingWorker 即可。在第二种变体中,如果简单克隆整个世界是 Not Acceptable ,那么让后台线程不仅计算世界的新状态,还计算修改世界图像的命令。 发布该命令,然后处理它们以更新图片。

关于java - 解决 Swingworker 应用程序中的并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12996602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com