[英]Java wait/notify implementation without synchronized
I have a scenario with dozens of producer and one single consumer. 我有几十个生产者和一个单一消费者的情景。 Timing is critical: for performance reason I want to avoid any locking of producers and I want the consumer to wait as little as possible when no messages are ready. 时机至关重要:出于性能原因,我想避免生产者的任何锁定,我希望消费者在没有消息准备就绪时尽可能少地等待。
I've started using a ConcurrentLinkedQueue, but I don't like to call sleep
on the consumer when queue.poll() == null
because I could waste precious milliseconds, and I don't want to use yield
because I end up wasting cpu. 我已经开始使用ConcurrentLinkedQueue了,但是当queue.poll() == null
时我不喜欢在使用者queue.poll() == null
调用sleep
,因为我可能浪费宝贵的毫秒数,而且我不想使用yield
因为我最终浪费了中央处理器。
So I came to implement a sort of ConcurrentBlockingQueue so that the consumer can run something like: 所以我来实现一种ConcurrentBlockingQueue,以便消费者可以运行如下:
T item = queue.poll();
if(item == null) {
wait();
item = queue.poll();
}
return item;
And producer something like: 和制片人一样:
queue.offer(item);
notify();
Unfortunately wait/notify only works on synchronized block, which in turn would drastically reduce producer performance. 不幸的是,wait / notify仅适用于synchronized块,这反过来会大大降低生产者的性能。 Is there any other implementation of wait/notify mechanism that does not require synchronization? 是否还有其他不需要同步的等待/通知机制实现?
I am aware of the risks related to not having wait and notify synchronized, and I managed to resolve them by having an external thread running the following: 我知道没有等待和通知同步的风险,我设法通过运行以下的外部线程来解决它们:
while(true) {
notify();
sleep(100);
}
I've started using a
ConcurrentLinkedQueue
, but I don't like to call sleep on the consumer whenqueue.poll() == null
我已经开始使用ConcurrentLinkedQueue
,但是当queue.poll() == null
时我不喜欢在使用者queue.poll() == null
调用sleep
You should check the BlockingQueue
interface , which has a take
method that blocks until an item becomes available. 您应该检查BlockingQueue
接口 ,该接口具有阻塞直到项目可用的take
方法。
It has several implementations as detailed in the javadoc, but ConcurrentLinkedQueue
is not one of them: 它有几个实现,详见javadoc,但ConcurrentLinkedQueue
不是其中之一:
All Known Implementing Classes: 所有已知的实现类:
ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue
I came out with the following implementation: 我出来了以下实现:
private final ConcurrentLinkedQueue<T> queue = new ConcurrentLinkedQueue<>();
private final Semaphore semaphore = new Semaphore(0);
private int size;
public void offer(T item) {
size += 1;
queue.offer(item);
semaphore.release();
}
public T poll(long timeout, TimeUnit unit) {
semaphore.drainPermits();
T item = queue.poll();
if (item == null) {
try {
semaphore.tryAcquire(timeout, unit);
} catch (InterruptedException ex) {
}
item = queue.poll();
}
if (item == null) {
size = 0;
} else {
size = Math.max(0, size - 1);
}
return item;
}
/** An inaccurate representation O(1)-access of queue size. */
public int size() {
return size;
}
With the following properties: 具有以下属性:
BlockingQueue
implementations that use Lock
in offer()
, or with synchronized blocks using wait/notify) 生产者永远不会进入SLEEP状态(我认为可以使用在offer()
中使用Lock
BlockingQueue
实现,或者使用wait / notify的synchronized块) sleep
, no yield
) 当队列为空时,消费者只进入睡眠状态,但只要生产者提供物品,它就会很快被唤醒(没有固定时间的sleep
,没有yield
) Is there any equivalent implementation in jdk that I'm not aware of? 在jdk中是否有任何我不知道的等效实现? Open for criticism. 开放批评。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.