在ConcurrentLinkedQueue中保持位置

时间:2018-02-06 18:59:36

标签: java queue

我需要维护一个InetSocketAdress对象列表。我有一个包含这些对象的ConcurrentLinkedQueue,我不想从队列中删除对象,但我需要知道我在队列中的位置。我有一个解决方案,但由于某种原因,我认为必须有一个更好的方法。

private static final ConcurrentLinkedQueue<InetSocketAddress> allSocketAddrs 
        = new ConcurrentLinkedQueue();
public List<InetSocketAddress> activeSocketAddrs = new ArrayList();
private Integer queuePos = 0;

public void addInetSocketAddr(InetSocketAddress isa){
    if(!allSocketAddrs.contains(isa)){
        allSocketAddrs.add(isa);
    }
}
private void getNewInetSokcetAddrs(){
    Object[] newAddrs = allSocketAddrs.toArray();

    for(int x = queuePos;x<newAddrs.length;x++){
        InetSocketAddress isa = (InetSocketAddress)newAddrs[x];
        //items added to this list CAN/WILL be removed.
        activeSocketAddrs.add(isa);
        queuePos++;
    }

1 个答案:

答案 0 :(得分:0)

我将&#34; all&#34;分开集合和新项目如下。在computeIfAbsent()中将元素添加到不同的集合中有点难看,但这样您就可以轻松高效地获取新项目。

示例使用LinkedBlockingQueue,因为ConcurrentLinkedQueue没有drainTogetAllNew()方法的工作方式也不同(批量获取新元素),因为您不需要主动更新活动列表。如果要逐个处理元素,可以直接访问队列。

private static final Map<InetSocketAddress, Object> allSocketAddrs = new ConcurrentHashMap<>();
private static final LinkedBlockingQueue<InetSocketAddress> activeSocketAddrs = new LinkedBlockingQueue<>();
private final static Object DUMMY = new Object();

public void addInetSocketAddr(InetSocketAddress isa){
    allSocketAddrs.computeIfAbsent(isa, key -> {
        activeSocketAddrs.add(key);
        return DUMMY;
    }
}

private List<InetSocketAddress> getAllNew() {
    List<InetSocketAddress> list = new ArrayList<>();
    activeSocketAddrs.drainTo(list);
    return list;
}
// Different threads could use this to get the queue and do a blocking
// take() for example
private Queue<InetSocketAddress> getNewQueue() {
    return activeSocketAddrs;
}