Fields Summary |
---|
private static final long | serialVersionUIDSerialization ID. This class relies on default serialization
even for the items array, which is default-serialized, even if
it is empty. Otherwise it could not be declared final, which is
necessary here. |
private final E[] | itemsThe queued items |
private transient int | takeIndexitems index for next take, poll or remove |
private transient int | putIndexitems index for next put, offer, or add. |
private int | countNumber of items in the queue |
private final ReentrantLock | lockMain lock guarding all access |
private final Condition | notEmptyCondition for waiting takes |
private final Condition | notFullCondition for waiting puts |
Constructors Summary |
---|
public ArrayBlockingQueue(int capacity)Creates an ArrayBlockingQueue with the given (fixed)
capacity and default access policy.
this(capacity, false);
|
public ArrayBlockingQueue(int capacity, boolean fair)Creates an ArrayBlockingQueue with the given (fixed)
capacity and the specified access policy.
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = (E[]) new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
|
public ArrayBlockingQueue(int capacity, boolean fair, Collection c)Creates an ArrayBlockingQueue with the given (fixed)
capacity, the specified access policy and initially containing the
elements of the given collection,
added in traversal order of the collection's iterator.
this(capacity, fair);
if (capacity < c.size())
throw new IllegalArgumentException();
for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
add(it.next());
|
Methods Summary |
---|
public void | clear()
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
int i = takeIndex;
int k = count;
while (k-- > 0) {
items[i] = null;
i = inc(i);
}
count = 0;
putIndex = 0;
takeIndex = 0;
notFull.signalAll();
} finally {
lock.unlock();
}
|
public boolean | contains(java.lang.Object o)
if (o == null) return false;
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
int i = takeIndex;
int k = 0;
while (k++ < count) {
if (o.equals(items[i]))
return true;
i = inc(i);
}
return false;
} finally {
lock.unlock();
}
|
public int | drainTo(java.util.Collection c)
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
int i = takeIndex;
int n = 0;
int max = count;
while (n < max) {
c.add(items[i]);
items[i] = null;
i = inc(i);
++n;
}
if (n > 0) {
count = 0;
putIndex = 0;
takeIndex = 0;
notFull.signalAll();
}
return n;
} finally {
lock.unlock();
}
|
public int | drainTo(java.util.Collection c, int maxElements)
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
if (maxElements <= 0)
return 0;
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
int i = takeIndex;
int n = 0;
int sz = count;
int max = (maxElements < count)? maxElements : count;
while (n < max) {
c.add(items[i]);
items[i] = null;
i = inc(i);
++n;
}
if (n > 0) {
count -= n;
takeIndex = i;
notFull.signalAll();
}
return n;
} finally {
lock.unlock();
}
|
private E | extract()Extract element at current take position, advance, and signal.
Call only when holding lock.
final E[] items = this.items;
E x = items[takeIndex];
items[takeIndex] = null;
takeIndex = inc(takeIndex);
--count;
notFull.signal();
return x;
|
final int | inc(int i)Circularly increment i.
// Internal helper methods
return (++i == items.length)? 0 : i;
|
private void | insert(E x)Insert element at current put position, advance, and signal.
Call only when holding lock.
items[putIndex] = x;
putIndex = inc(putIndex);
++count;
notEmpty.signal();
|
public java.util.Iterator | iterator()Returns an iterator over the elements in this queue in proper sequence.
The returned Iterator is a "weakly consistent" iterator that
will never throw {@link java.util.ConcurrentModificationException},
and guarantees to traverse elements as they existed upon
construction of the iterator, and may (but is not guaranteed to)
reflect any modifications subsequent to construction.
final ReentrantLock lock = this.lock;
lock.lock();
try {
return new Itr();
} finally {
lock.unlock();
}
|
public boolean | offer(E o)Inserts the specified element at the tail of this queue if possible,
returning immediately if this queue is full.
if (o == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
insert(o);
return true;
}
} finally {
lock.unlock();
}
|
public boolean | offer(E o, long timeout, java.util.concurrent.TimeUnit unit)Inserts the specified element at the tail of this queue, waiting if
necessary up to the specified wait time for space to become available.
if (o == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
long nanos = unit.toNanos(timeout);
for (;;) {
if (count != items.length) {
insert(o);
return true;
}
if (nanos <= 0)
return false;
try {
nanos = notFull.awaitNanos(nanos);
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
}
} finally {
lock.unlock();
}
|
public E | peek()
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : items[takeIndex];
} finally {
lock.unlock();
}
|
public E | poll()
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == 0)
return null;
E x = extract();
return x;
} finally {
lock.unlock();
}
|
public E | poll(long timeout, java.util.concurrent.TimeUnit unit)
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
long nanos = unit.toNanos(timeout);
for (;;) {
if (count != 0) {
E x = extract();
return x;
}
if (nanos <= 0)
return null;
try {
nanos = notEmpty.awaitNanos(nanos);
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
throw ie;
}
}
} finally {
lock.unlock();
}
|
public void | put(E o)Adds the specified element to the tail of this queue, waiting if
necessary for space to become available.
if (o == null) throw new NullPointerException();
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == items.length)
notFull.await();
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
insert(o);
} finally {
lock.unlock();
}
|
public int | remainingCapacity()Returns the number of elements that this queue can ideally (in
the absence of memory or resource constraints) accept without
blocking. This is always equal to the initial capacity of this queue
less the current size of this queue.
Note that you cannot always tell if
an attempt to add an element will succeed by
inspecting remainingCapacity because it may be the
case that a waiting consumer is ready to take an
element out of an otherwise full queue.
final ReentrantLock lock = this.lock;
lock.lock();
try {
return items.length - count;
} finally {
lock.unlock();
}
|
public boolean | remove(java.lang.Object o)
if (o == null) return false;
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
int i = takeIndex;
int k = 0;
for (;;) {
if (k++ >= count)
return false;
if (o.equals(items[i])) {
removeAt(i);
return true;
}
i = inc(i);
}
} finally {
lock.unlock();
}
|
void | removeAt(int i)Utility for remove and iterator.remove: Delete item at position i.
Call only when holding lock.
final E[] items = this.items;
// if removing front item, just advance
if (i == takeIndex) {
items[takeIndex] = null;
takeIndex = inc(takeIndex);
} else {
// slide over all others up through putIndex.
for (;;) {
int nexti = inc(i);
if (nexti != putIndex) {
items[i] = items[nexti];
i = nexti;
} else {
items[i] = null;
putIndex = i;
break;
}
}
}
--count;
notFull.signal();
|
public int | size()Returns the number of elements in this queue.
final ReentrantLock lock = this.lock;
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
|
public E | take()
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == 0)
notEmpty.await();
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
throw ie;
}
E x = extract();
return x;
} finally {
lock.unlock();
}
|
public java.lang.Object[] | toArray()
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] a = new Object[count];
int k = 0;
int i = takeIndex;
while (k < count) {
a[k++] = items[i];
i = inc(i);
}
return a;
} finally {
lock.unlock();
}
|
public T[] | toArray(T[] a)
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (a.length < count)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(),
count
);
int k = 0;
int i = takeIndex;
while (k < count) {
a[k++] = (T)items[i];
i = inc(i);
}
if (a.length > count)
a[count] = null;
return a;
} finally {
lock.unlock();
}
|
public java.lang.String | toString()
final ReentrantLock lock = this.lock;
lock.lock();
try {
return super.toString();
} finally {
lock.unlock();
}
|