package org.jctools.queues.blocking;
import org.jctools.queues.spec.ConcurrentQueueSpec;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public final class McParkTakeStrategy<E> implements TakeStrategy<E>
{
private final ReentrantLock lock = new ReentrantLock();
private final Condition cond = lock.newCondition();
private int waiters = 0;
@Override
public void signal()
{
ReentrantLock l = lock;
l.lock();
try
{
if (waiters>0)
{
cond.signal();
}
}
finally
{
l.unlock();
}
}
@Override
public E waitPoll(Queue<E> q) throws InterruptedException
{
E e = q.poll();
if (e != null)
{
return e;
}
ReentrantLock l = lock;
l.lock();
try
{
while((e = q.poll())==null)
{
waiters++;
cond.await();
waiters--;
}
}
finally
{
l.unlock();
}
return e;
}
@Override
public boolean supportsSpec(ConcurrentQueueSpec qs)
{
return true;
}
}