Java中用ArrayDeque构造函数拷贝并发集合是否存在线程安全问题?
问题分析:ConcurrentLinkedDeque构造ArrayDeque时的并发安全问题
你的实现方式不会抛出并发修改异常,但拷贝结果是弱一致性的,具体细节如下:
为什么不会崩溃?
ConcurrentLinkedDeque是Java提供的无锁并发集合,它的迭代器是弱一致性的——迭代过程中即使其他线程修改原集合,也不会抛出ConcurrentModificationException,迭代器会反映创建时或之后某个时刻的集合状态,不会出现遍历崩溃的情况。而ArrayDeque的构造函数本质是通过遍历传入集合的迭代器来填充元素,所以整个拷贝过程是安全的,不会因并发写入抛出异常。拷贝结果的局限性
这种方式无法得到原集合在某个精确时间点的完整快照:如果拷贝过程中其他线程新增/删除元素,拷贝后的ArrayDeque可能包含新增的元素,也可能不包含;同理,已删除的元素可能还存在于拷贝结果中,取决于操作发生的时机。如何获取精确快照?
如果需要严格的一致性快照(即拷贝结果完全对应原集合某一时刻的状态),需要额外的同步措施:- 给原ConcurrentLinkedDeque加显式锁(比如
ReentrantLock),在锁的保护下完成拷贝操作,确保拷贝期间其他线程无法修改原集合。 - 示例代码:
ReentrantLock lock = new ReentrantLock(); // ... 原集合的所有修改操作都需先获取该锁 lock.lock(); try { ledger_copy = new ArrayDeque<>(ledger); } finally { lock.unlock(); }
- 给原ConcurrentLinkedDeque加显式锁(比如
内容的提问来源于stack exchange,提问作者chilliefiber
相关产品推荐
相关产品推荐

