我需要一个具有固定容量的Java列表,但它总是允许线程在开始时添加项目。如果它已满,则应从末尾移除一个项目以腾出空间。没有其他进程会删除项目,但其他进程将希望迭代项目。
JDK中有什么东西允许我原子地做这个吗?
我目前的计划是使用一些现有的线程安全集合(例如LinkedBlockingQueue),并在检查容量/添加/删除时进一步同步它。那还行吗?
感谢。
答案 0 :(得分:1)
您的想法可行,但会涉及取出多重锁(请参阅下面的示例)。鉴于您在添加数据时需要同步多个操作,您也可以将LinkedList
的{{1}}实现包装到以避免额外锁定的开销。
Queue
答案 1 :(得分:0)
我正在使用Java的旧版本(是的1.3,我别无选择),所以即使它在以后的Javas中也存在,我也无法使用它。所以我按照以下方式编码:
public class Fifo {
private LinkedList fifoContents = new LinkedList();
public synchronized void put(Object element) {
if ( fifoContents.size() > 100){
fifoContents.removeFirst();
logger.logWarning("*** Backlog, discarding messaage ");
}
fifoContents.add (element);
return;
}
public synchronized Object get() throws NoSuchElementException {
return fifoContents.removeFirst();
}
}
答案 2 :(得分:0)
您可以在没有额外锁定的情况下完成测试/移除/插入:
class DroppingQueue<E>
extends ArrayBlockingQueue<E> {
public boolean add(E item) {
while (! offer(item)) {
take();
}
return true;
}
}
虽然此方法未同步,add
和offer
仍然存在,所以最糟糕的情况是线程#1将调用offer
,发现队列已满,线程#2将执行相同的操作,并且在两个线程成功添加项目之前,两者都将删除项目,暂时将项目数量减少到小于最大值。这可能不会导致严重的问题。
答案 3 :(得分:0)
JDK中没有这样的课程。 如果你要实现这样的集合,你可能想要使用带浮动头/尾指针的数组 - 因为你有固定的大小,你根本不需要链表。