我想知道是否可以使用AtomicReferenceArray替代ConcurrentLinkedQueue(如果可以使用有限结构)。

我目前有类似的东西:

ConcurrentLinkedQueue<Object[]> queue = new ConcurrentLinkedQueue<Object[]>();

public void store(Price price, Instrument instrument, Object[] formats){
     Object[] elements = {price, instrument, formats};
     queue.offer( elements);
}


store(..)由多个线程调用。

我还有一个使用者线程,该线程会定期唤醒并使用这些元素。

private class Consumer implements Runnable{

@Override
public void run(){

List<Object[]> holder = drain( queue );
for(Object[] elements : holder ){
   for( Object e : elements ){
      //process ...
   }
}

private final List<Object[]> drain(){
//...
}

}


我可以换掉ConcurrentLinkedQueue以便使用AtomicReferenceArray并仍然保持线程安全性吗?

具体来说,原子地存储元素并建立“先发生”关系,以便使用者线程看到不同线程存储的所有元素吗?

我尝试阅读AtomicReferenceArray的源代码,但仍不确定。

干杯

最佳答案

AtomicReferenceArray可用作无锁定的单个使用者/多生产者环形缓冲区。几个月前,我在experimenting处实现,并且有一个可以正常工作的原型。这样做的好处是减少了垃圾的创建,更好的缓存局部性,并且由于更简单而没有满时的性能也更好。缺点是缺乏严格的fifo语义,并且当缓冲区已满时性能很差,因为生产者必须等待流失发生。可以通过回退到ConcurrentLinkedQueue以避免停顿来缓解这种情况。

制片人必须看到事前发生的边缘,以便他们获得唯一的广告位。但是,由于只需要一个消耗器,因此可以将其延迟到排空完成为止。在我的用法中,消耗在线程之间摊销,因此通过成功获取尝试锁来选择使用者。该锁的释放提供了优势,从而允许阵列更新在关键部分内使用惰性集。

我只会在对性能进行高度调整的特殊情况下使用此方法。在我的用法中,将其作为缓存的内部实现细节是有意义的。不过,我一般不会使用它。

09-30 22:16