我正在寻找具有以下功能的java.util.Set实现:
据我所知,唯一合适的impl是CopyOnWriteArraySet,但它在文档中指出:
变异操作(添加,设置,删除, 它们很昂贵,因为它们通常需要复制整个 底层数组。
在我的情况下,我有很多插入到队列末尾(set)和批量从队列的头部删除(和读取)。那么,有什么建议吗?
答案 0 :(得分:6)
以下解决方案在删除时存在竞争条件。它的行为与标准JDK Set实现略有不同。
但是,它使用标准的JDK对象,并且是一个简单的实现。只有你可以决定这种竞争条件是否可以接受,或者你是否愿意投入时间来寻找/实施没有比赛的解决方案。
public class FifoSet<T>
{
private ConcurrentHashMap<T,T> _map;
private ConcurrentLinkedQueue<T> _queue;
public void add(T obj)
{
if (_map.put(obj,obj) != null)
return;
_queue.add(obj);
}
public T removeFirst()
{
T obj = _queue.remove();
_map.remove(obj);
return obj;
}
}
更多解释:ConcurrentHashMap
仅作为ConcurrentLinkedList
的守卫而存在;它的put()
方法本质上是一个比较和交换。因此,在添加到队列之前,确保地图中没有任何内容,并且在从队列中删除之前不会从地图中删除。
删除时的竞争条件是从队列中删除项目并将其从地图中删除之间有一段时间。在那段时间内,add会失败,因为它仍然认为该项目在队列中。
这是一个相对较小的竞争条件。一个远远不如从队列中删除项目和实际对该项目执行某些操作之间的时间差的重要性。