我需要维护一个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++;
}
答案 0 :(得分:0)
我将&#34; all&#34;分开集合和新项目如下。在computeIfAbsent()
中将元素添加到不同的集合中有点难看,但这样您就可以轻松高效地获取新项目。
示例使用LinkedBlockingQueue
,因为ConcurrentLinkedQueue
没有drainTo
。 getAllNew()
方法的工作方式也不同(批量获取新元素),因为您不需要主动更新活动列表。如果要逐个处理元素,可以直接访问队列。
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;
}