[英]How to make a CircularFifoQueue threadsafe?
我想使用帶有Spring ExecutorService
的CircularFifoQueue
。
以下內容無法編譯,因為CircularFifoQueue
的類型不是BlockingQueue
。 但這顯示了我正在努力實現的目標:
int threads = 10;
int queueSize = 500;
new java.util.concurrent.ThreadPoolExecutor(threads, threads, 0L, TimeUnit.MILLISECONDS,
new CircularFifoQueue(queueSize));
附:
package org.apache.commons.collections4.queue;
public class CircularFifoQueue<E> extends AbstractCollection<E>
implements Queue<E>, BoundedCollection<E>, Serializable
問題:上面的代碼是否提供線程安全性(因為CircularFifoQueue
本身不是線程安全的)? 如果沒有,如何使它具有線程安全性?
實際上,您將必須編寫自己的隊列實現。 由於CircularFifoQueue使用底層數組來保存元素,因此我將以java.util.concurrent包中的ArrayBlockingQueue數據結構為幫助。
范例:
class ThreadSafeCircularFifoQueue<T> extends CircularFifoQueue<T> implements BlockingQueue<T> {
/** Main lock guarding all access */
final ReentrantLock lock;
/** Condition for waiting takes */
private final Condition notEmpty;
/** Condition for waiting puts */
private final Condition notFull;
@Override
public int size() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return super.size();
} finally {
lock.unlock();
}
}
//and so forth
}
您可以使用commons-collections QueueUtils.synchronizedQueue進行同步
Queue queue = QueueUtils.synchronizedQueue(new CircularFifoQueue());
但是根據javadoc,它需要額外的同步才能進行串行訪問:
為了保證串行訪問,至關重要的是,對后備隊列的所有訪問都必須通過返回的隊列來完成。
當用戶遍歷返回的隊列時,必須手動對其進行同步:
Queue queue = QueueUtils.synchronizedQueue(new CircularFifoQueue()); ... synchronized(queue) { Iterator i = queue.iterator(); // Must be in synchronized block while (i.hasNext()) foo(i.next()); } }
不遵循此建議可能導致不確定的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.