java - 如何防止ConcurrentModificationException?

标签 java multithreading sockets

我有一些代码,允许服务器生成一些地形,然后通过数据报包将该数据发送到单独的客户端程序。客户端接收该数据的伪代码如下:

-client sends SYN message to server
-server responds with ACK message (using 2-step SYNACK)
-client sends request for terrain from x=0 to x=32
-server responds with 32 seperate packets, one for each x (to keep packet size small)
-client receives packets and puts data into an ArrayList

在我当前的解决方案中,客户端正在运行两个并发线程,一个用于将数据绘制到屏幕的图形线程,以及一个数据包接收器线程(因为数据报套接字中的 .receive() 函数会挂起,直到收到数据包为止) .

目前,如果在图形更新方法运行时 32 个地形数据包之一到达,则会发生并发修改异常。

我想到了两种可能的解决方案:

  1. 数据包到达时将其保存并在图形线程中处理它(但是,如果图形挂起时数据包到达太快,则可能会导致数据包丢失)。
  2. 使用一个变量来导致数据包接收器挂起,该变量可以在图形更新中设置。

但这两种解决方案似乎都不理想,而且都有其缺陷。对于我的问题有一个好的解决方案吗?如果没有,那么最好使用上述哪一种解决方案?

最佳答案

我建议使用队列在线程之间传递数据,而不是列表或集合。

如果您使用 ArrayBlockingQueue 或 ConcurrentLinkedQueue 等并发队列,则它们都不会触发 CME。

注意:我建议您避免使用迭代器,而是调用 take()poll() 从队列中提取事件。

关于java - 如何防止ConcurrentModificationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37103339/

相关文章:

sockets - 通过 LISP USOCKET 接收数据

linux - tcpdump 显示数据包,但应用程序显示数据包是突发的

java - Python 服务器没有从 Java 客户端接收到完整的字符串

java - Spring Boot Primitive Rest Controller 返回 Whitelabel 错误页面

java - TimeSeriesChart 的最大范围值是多少

java - Hibernate Session 和线程安全

Java数组随机存储对象

java - Apache Tomcat 10.0.0-M1 使用 JSP 绝对 uri http ://java. sun.com/jsp/jSTL/core 无法解析

java - tomcat 没有发送请求的 http-header

ios - DispatchQueue.main.async 和 DispatchQueue.main.sync 的区别