0

我有主线程和 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) {......

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

4

2 回答 2

4

您需要同步对 的访问clientSockets,因为不允许您更改Listwhile 迭代它的结构。

一个简单的解决方案是创建clientSockets一个同步集合,然后在迭代之前显式同步它:

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


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

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

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

于 2012-09-09T13:49:58.533 回答
0

Javadoc 说“如果多个线程同时访问一个 ArrayList 实例,并且至少有一个线程在结构上修改了列表,那么它必须在外部同步。(结构修改是添加或删除一个或多个元素,或显式调整列表大小的任何操作)后备数组;仅设置元素的值不是结构修改。”。

只是设置标签不是结构修改,所以我不确定这是否是异常的原因。

于 2012-09-09T14:16:21.243 回答