我怎样才能原子化;如果有空闲空间,请排队,或退出,然后排队”;对于Java队列/列表?

我怎样才能原子化;如果有空闲空间,请排队,或退出,然后排队”;对于Java队列/列表?,java,multithreading,concurrency,Java,Multithreading,Concurrency,在Java中,我需要一个具有固定容量的列表,但它总是允许线程在开始时添加项目。如果已满,则应从末端移除一个项目以腾出空间。没有其他进程将删除项,但其他进程希望迭代这些项 JDK中是否有允许我以原子方式执行此操作的内容 我目前的计划只是使用一些现有的threadsafe集合(例如LinkedBlockingQueue),并在检查容量/添加/删除时在其上进一步同步。那也行吗 谢谢。我使用的是旧版本的Java(是的,1.3,我没有选择),所以即使它在以后的Java中,我也不能使用它。所以我按照这些思路

在Java中,我需要一个具有固定容量的列表,但它总是允许线程在开始时添加项目。如果已满,则应从末端移除一个项目以腾出空间。没有其他进程将删除项,但其他进程希望迭代这些项

JDK中是否有允许我以原子方式执行此操作的内容

我目前的计划只是使用一些现有的threadsafe集合(例如LinkedBlockingQueue),并在检查容量/添加/删除时在其上进一步同步。那也行吗


谢谢。

我使用的是旧版本的Java(是的,1.3,我没有选择),所以即使它在以后的Java中,我也不能使用它。所以我按照这些思路编码:

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();
 }
}

您的想法可行,但需要取出多个锁(参见下面的示例)。如果在添加数据时需要同步多个操作,那么最好将
链接列表
队列的实现包装为以避免额外锁的开销

// Create queue with fixed capacity.
Queue<Item> queue = new LinkedBlockingQueue<Item>(1000);

...

// Attempt to add item to queue, removing items if required.
synchronized(queue) { // First lock
  while (!queue.offer(item)) { // Second lock
    queue.take(); // Third lock
  }
}
//创建具有固定容量的队列。
队列队列=新的LinkedBlockingQueue(1000);
...
//尝试将项目添加到队列,并在需要时删除项目。
已同步(队列){//第一个锁
而(!queue.offer(item)){//第二个锁
queue.take();//第三个锁
}
}

您可能只需测试/移除/插入锁,而不需要额外的锁:

class DroppingQueue<E>
extends ArrayBlockingQueue<E> {
    public boolean add(E item) {
        while (! offer(item)) {
            take();
        }
        return true;
    }
}
类丢弃队列
扩展ArrayBlockingQueue{
公共布尔添加(E项){
而(!报价(项目)){
take();
}
返回true;
}
}

虽然此方法不同步,
add
offer
仍然同步,因此可能发生的最坏情况是线程1将调用
offer
,发现队列已满,线程2将执行相同操作,并且两者都将删除项目,暂时将项目数量减少到最大值以下,在两个线程成功添加其项之前。这可能不会导致严重的问题。

JDK中没有这样的类。
如果您要实现这样的集合,您可能希望使用带有浮动头/尾指针的数组-因为您有固定的大小,所以根本不需要链表。

有趣的用例,JDK似乎没有涵盖。我认为这种解决方案可能发生的最坏情况是,每次线程#1获取一项,在线程#1继续之前,其他一些线程提供另一项。然而,这种可能性比您的场景要小。