public E take() throws InterruptedException {
final ReentrantLock lock =
this
.lock;
lock.lockInterruptibly();
E result;
try
{
while
( (result = dequeue()) ==
null
)
notEmpty.await();
} finally {
lock.unlock();
}
return
result;
}
private E dequeue() {
int n = size - 1;
if
(n < 0)
return
null
;
else
{
Object[] array = queue;
E result = (E) array[0];
E x = (E) array[n];
array[n] =
null
;
Comparator<?
super
E> cmp = comparator;
if
(cmp ==
null
)
siftDownComparable(0, x, array, n);
else
siftDownUsingComparator(0, x, array, n, cmp);
size = n;
return
result;
}
}
private static <T> void siftDownComparable(int k, T x, Object[] array,
int n) {
if
(n > 0) {
Comparable<?
super
T> key = (Comparable<?
super
T>)x;
int half = n >>> 1;
while
(k < half) {
int child = (k << 1) + 1;
Object c = array[child];
int right = child + 1;
if
(right < n &&
((Comparable<?
super
T>) c).compareTo((T) array[right]) > 0)
c = array[child = right];
if
(key.compareTo((T) c) <= 0)
break
;
array[k] = c;
k = child;
}
array[k] = key;
}
}