我想使用CircularFifoQueue
加上ExecutorService
。
以下内容无法编译,因为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
本身不是线程安全的)?
如果没有,我怎样才能使它成为线程安全的?
答案 0 :(得分:2)
工作队列意味着阻止,因此您需要添加CircularFifoQueue
以使BLockingQueue
成为class BlockingCircularFifoQueue<E> implements BlockingQueue<E>{
private CircularFifoQueue<E> backingCollection;
...
}
。
----------------
| ID | Pages |
----------------
| 1 | page1 |
----------------
| 2 | page2 |
----------------
并在需要时委托支持集合。 当然,你需要Conditions和Lock。
答案 1 :(得分:1)
您必须实际编写自己的队列实现。 由于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
}
答案 2 :(得分:1)
您可以使用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()); } }
不遵循此建议可能导致不确定的行为。