java - 从另一个线程向 ArrayList 添加内容

标签 java

我有主线程和ClientThread... 在主线程中,当用户连接到服务器时,它会调用 ClientThread 中的方法

    try {
        Socket socket = server.accept();
        clientThread.addClient(socket);
    } catch(Exception e) {
        e.printStackTrace();
    }

ClientThread 中的方法将内容添加到 ArrayList

public void addClient(Socket socket) {
    clientSockets.add(socket);
}

ClientThread 还在每一帧上运行此代码:

        for (Socket socket : clientSockets) {
            label.setText(socket.toString());
        }

由于某种原因,我在这一行得到这个错误java.util.ConcurrentModificationException for (Socket socket : clientSockets) {...

问题:为什么我会收到此错误,如何修复该错误?

最佳答案

您需要同步对 clientSockets 的访问,因为不允许您在迭代 List 时更改其结构。

一个简单的解决方案是使 clientSockets 成为一个同步集合,然后在迭代之前显式对其进行同步:

List<Socket> clientSockets = Collections.synchronizedList(new ArrayList<Socket>());


//...when setting the labels:
synchronized (clientSockets) {
    for ( Socket socket : clientSockets ) {
        label.setText(socket.toString());
    }
}

无论您在列表的何处进行迭代,都需要执行相同的操作。

您还可以考虑使用像 CopyOnArrayList 这样的东西,它不需要您同步,但代价是使用更多内存并可能提供稍微陈旧的数据。

关于java - 从另一个线程向 ArrayList 添加内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12339592/

相关文章:

java - java中字节的奇怪行为

java - SubethaSmtp 工作示例

java - 为什么不在模板中显示 Playframework 自定义验证消息

java - 添加到通用列表<?> 产生编译错误

java - 在Java中将 boolean 值转换为int

java - IF 条件在 Java Selenium 中不起作用

Java:链表deleteFirst()方法

java - 使用 JDK 7 编译的 scala 代码可以在 JVM 8 上运行吗?

java - 如果小程序在浏览器的 JRE 中运行,为什么机器上需要 JRE?

java - 在 Java 中使用列表来存储用户输入并执行任务