You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java技术问题:RMI客户端ArrayList在GUI中获取大小异常的解决咨询

嘿,这个问题我之前也碰到过类似的情况,大概率是对象引用不共享或者线程可见性的问题导致的,咱们一步步来排查解决:

1. 先排查GUI和RMI客户端是否共享同一个TemperatureList实例

这是最常见的原因:你在RMI客户端类里维护的那个正在被填充数据的TemperatureList,和GUI代码里用来获取大小的集合,是不是同一个对象?

比如如果你的GUI类里是这么写的:

// GUI类里错误的写法:重新创建了空集合
ArrayList<Temperature> TemperatureList = new ArrayList<>();

那不管RMI客户端那边的集合怎么加数据,GUI这边的都是空的,自然大小永远是0。

解决办法:
把RMI客户端里的TemperatureList实例传递给GUI类,确保二者共享同一个集合:

  • 比如在GUI类的构造方法里传入集合:
public class TempGUI extends JFrame {
    private ArrayList<Temperature> temperatureList;

    // 通过构造函数传入共享的集合实例
    public TempGUI(ArrayList<Temperature> sharedList) {
        this.temperatureList = sharedList;
        // 初始化按钮点击事件
        JButton showSizeBtn = new JButton("显示集合大小");
        showSizeBtn.addActionListener(e -> {
            JOptionPane.showMessageDialog(this, "集合大小:" + temperatureList.size());
        });
        // 其他GUI初始化代码...
    }
}
  • 然后在RMI客户端里创建GUI时,把自己的集合传进去:
// RMI客户端类中
ArrayList<Temperature> TemperatureList = new ArrayList<>();
TempGUI gui = new TempGUI(TemperatureList);
gui.setVisible(true);

2. 处理线程安全与内存可见性问题

因为TemperatureSensor是定期生成数据,大概率是在单独的线程里操作集合(比如用Timer或者ScheduledExecutorService),而GUI的事件监听是在AWT/Swing的事件调度线程(EDT)里执行的。

普通的ArrayList本身不是线程安全的,而且不同线程之间的内存可见性没有保障——也就是说,GUI线程可能看不到其他线程对集合做的修改,所以拿到的还是初始的0。

解决办法:

  • 方案一:改用线程安全的集合类,比如CopyOnWriteArrayList,它会自动处理线程安全和内存可见性问题:
// 把原来的ArrayList换成CopyOnWriteArrayList
CopyOnWriteArrayList<Temperature> TemperatureList = new CopyOnWriteArrayList<>();
  • 方案二:在访问和修改集合的时候,加上同步锁,确保线程间的可见性:
    • 修改集合时(TemperatureSensor添加元素):
    synchronized (TemperatureList) {
        TemperatureList.add(0, new Temperature(randomValue));
    }
    
    • GUI获取大小时:
    JButton showSizeBtn = new JButton("显示集合大小");
    showSizeBtn.addActionListener(e -> {
        int size;
        synchronized (TemperatureList) {
            size = TemperatureList.size();
        }
        JOptionPane.showMessageDialog(this, "集合大小:" + size);
    });
    

3. 确认RMI客户端的集合没有被意外重置

有时候可能在RMI的某些操作中,不小心重新赋值了TemperatureList变量,比如:

// 错误操作:重新创建集合,导致原来的引用失效
TemperatureList = new ArrayList<>();

这种情况会导致GUI引用的还是旧的空集合,而RMI客户端里的新集合有数据,但GUI完全拿不到。

解决办法:
检查RMI客户端中所有涉及TemperatureList的代码,确保没有重新赋值的操作,始终对同一个集合实例进行修改。


内容的提问来源于stack exchange,提问作者RollerMobster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:35:18