当多个线程通过 RMI 访问同一服务器时,我的程序遇到问题。服务器包含一个列表作为缓存并执行一些昂贵的计算,有时会更改该列表。计算完成后,列表将被序列化并发送给客户端。
第一个问题:如果列表在被序列化(例如,由不同的客户端请求某些数据)时发生更改ConcurrentModificationException
(可能)抛出一个,导致EOFException
RMI 调用/客户端的反序列化。
因此,我需要某种列表结构,它对于序列化是“稳定的”,同时可能被不同的线程更改。
我们尝试过的解决方案:
- 常规 ArrayList / Set - 由于并发而无法正常工作
- 在每次序列化之前深度复制整个结构 - faaar 太昂贵了
CopyOnWriteArrayList
- 也很昂贵,因为它复制了列表和
揭示第二个问题:我们需要能够以原子方式替换列表中当前不是线程安全的任何元素(首先删除,然后添加(这甚至更昂贵)),或者只能通过锁定列表来实现,因此只做不同的线程按顺序排列。
因此我的问题是:
您是否知道
Collection
允许我们对serialize
Collection 线程安全的实现,而其他线程对其进行修改,and
其中包含某种方式的atomically replacing
元素?如果列表
not
需要copied
在序列化之前出现,那将是一个奖励!为每个序列化创建一个快照是可以的,但仍然是 meh :/
问题说明(C=compute,A=add to list,R=remove from list,S=serialize)
Thread1 Thread2
C
A
A C
C A
S C
S R <---- Remove and add have to be performed without Thread1 serializing
S A <---- anything in between (atomically) - and it has to be done without
S S blocking other threads computations and serializations for long
S and not third thread must be allowed to start serializing in this
S in-between state
S