Wednesday, November 17, 2010

ConcurrentQueue using Lock-Conditions

package self.synchronization;
import java.util.concurrent.locks.*;

public class BlockingQueue3
{
private Node head = null;
private Node tail = null;
private final Lock lock = new ReentrantLock();
private final Condition itemAvailableCondition = lock.newCondition();
private final Condition spaceAvailableCondition = lock.newCondition();

private final int maxCount = 10; // make this a constructor param
private volatile int currentCount = 0;

public void produce(T item) throws InterruptedException {
Node newTail = new Node(item, null);
try
{
this.lock.lock();
// condition
while (this.currentCount >= maxCount) {
spaceAvailableCondition.await();
}

if (tail != null) {
tail.next = newTail;
} else {
tail = newTail;
head = newTail;
}

++this.currentCount;
this.itemAvailableCondition.signal();
}
finally
{
this.lock.unlock();
}

}

public T consume() throws InterruptedException {
Node returnNode = null;
try
{
this.lock.lock();
// condition
while (currentCount == 0) {
this.itemAvailableCondition.await();
}

returnNode = head;
head = head.next;
if (head == null)
tail = null;
--currentCount;
this.spaceAvailableCondition.signal();
}
finally
{
this.lock.unlock();
}

return returnNode.item;
}

private class Node {
public final T item;
public Node next;

Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
}

No comments: