I implemented my custom BlockingQueue<T>
and compared it with java.util.concurrent
ArrayBlockingQueue
.
Here is my implementation:
public class CustomBlockingQueue<T> implements BlockingQueue<T> {
private final T[] table;
private final int capacity;
private int head = 0;
private int tail = 0;
private volatile int size;
private final Lock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();
@SuppressWarnings("unchecked")
public CustomBlockingQueue(final int capacity) {
this.capacity = capacity;
this.table = (T[]) new Object[this.capacity];
size = 0;
}
@Override
public void add(final T item) throws InterruptedException {
lock.lock();
try {
while (size >= table.length) {
notFull.await();
}
if (tail == table.length) {
tail = 0;
}
table[tail] = item;
size++;
tail++;
if (size == 1) {
notEmpty.signalAll();
}
} finally {
lock.unlock();
}
}
@Override
public T poll() throws InterruptedException {
lock.lock();
try {
while (size == 0) {
notEmpty.await();
}
if (head == table.length) {
head = 0;
}
final T result = table[head];
table[head] = null;
size--;
head++;
if (size == capacity - 1) {
notFull.signalAll();
}
return result;
} finally {
lock.unlock();
}
}
@Override
public int size() {
return size;
}
}
My implementation is based on the array.
I don't ask you to review the code but help me to clarify the difference between my one and Java's.
In my code I do notEmpty.signalAll()
or notFull.signalAll()
inside the if
clause but java.util.concurrent
one simply invokes signal()
in each case?
What is the reason for notifying another thread each time even when there's no necessary in it?