diff options
author | Andrew Haley <aph@redhat.com> | 2016-09-30 16:24:48 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2016-09-30 16:24:48 +0000 |
commit | 07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch) | |
tree | 3f22b3241c513ad168c8353805614ae1249410f4 /libjava/classpath/external/jsr166/java/util | |
parent | eae993948bae8b788c53772bcb9217c063716f93 (diff) | |
download | gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.zip gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.gz gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.bz2 |
Makefile.def: Remove libjava.
2016-09-30 Andrew Haley <aph@redhat.com>
* Makefile.def: Remove libjava.
* Makefile.tpl: Likewise.
* Makefile.in: Regenerate.
* configure.ac: Likewise.
* configure: Likewise.
* gcc/java: Remove.
* libjava: Likewise.
From-SVN: r240662
Diffstat (limited to 'libjava/classpath/external/jsr166/java/util')
70 files changed, 0 insertions, 31674 deletions
diff --git a/libjava/classpath/external/jsr166/java/util/AbstractQueue.java b/libjava/classpath/external/jsr166/java/util/AbstractQueue.java deleted file mode 100644 index 644df6c..0000000 --- a/libjava/classpath/external/jsr166/java/util/AbstractQueue.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util; - -/** - * This class provides skeletal implementations of some {@link Queue} - * operations. The implementations in this class are appropriate when - * the base implementation does <em>not</em> allow <tt>null</tt> - * elements. Methods {@link #add add}, {@link #remove remove}, and - * {@link #element element} are based on {@link #offer offer}, {@link - * #poll poll}, and {@link #peek peek}, respectively but throw - * exceptions instead of indicating failure via <tt>false</tt> or - * <tt>null</tt> returns. - * - * <p> A <tt>Queue</tt> implementation that extends this class must - * minimally define a method {@link Queue#offer} which does not permit - * insertion of <tt>null</tt> elements, along with methods {@link - * Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and a - * {@link Collection#iterator} supporting {@link - * Iterator#remove}. Typically, additional methods will be overridden - * as well. If these requirements cannot be met, consider instead - * subclassing {@link AbstractCollection}. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ -public abstract class AbstractQueue<E> - extends AbstractCollection<E> - implements Queue<E> { - - /** - * Constructor for use by subclasses. - */ - protected AbstractQueue() { - } - - /** - * Inserts the specified element into this queue if it is possible to do so - * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt> - * if no space is currently available. - * - * <p>This implementation returns <tt>true</tt> if <tt>offer</tt> succeeds, - * else throws an <tt>IllegalStateException</tt>. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws IllegalStateException if the element cannot be added at this - * time due to capacity restrictions - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this queue - * @throws NullPointerException if the specified element is null and - * this queue does not permit null elements - * @throws IllegalArgumentException if some property of this element - * prevents it from being added to this queue - */ - public boolean add(E e) { - if (offer(e)) - return true; - else - throw new IllegalStateException("Queue full"); - } - - /** - * Retrieves and removes the head of this queue. This method differs - * from {@link #poll poll} only in that it throws an exception if this - * queue is empty. - * - * <p>This implementation returns the result of <tt>poll</tt> - * unless the queue is empty. - * - * @return the head of this queue - * @throws NoSuchElementException if this queue is empty - */ - public E remove() { - E x = poll(); - if (x != null) - return x; - else - throw new NoSuchElementException(); - } - - /** - * Retrieves, but does not remove, the head of this queue. This method - * differs from {@link #peek peek} only in that it throws an exception if - * this queue is empty. - * - * <p>This implementation returns the result of <tt>peek</tt> - * unless the queue is empty. - * - * @return the head of this queue - * @throws NoSuchElementException if this queue is empty - */ - public E element() { - E x = peek(); - if (x != null) - return x; - else - throw new NoSuchElementException(); - } - - /** - * Removes all of the elements from this queue. - * The queue will be empty after this call returns. - * - * <p>This implementation repeatedly invokes {@link #poll poll} until it - * returns <tt>null</tt>. - */ - public void clear() { - while (poll() != null) - ; - } - - /** - * Adds all of the elements in the specified collection to this - * queue. Attempts to addAll of a queue to itself result in - * <tt>IllegalArgumentException</tt>. Further, the behavior of - * this operation is undefined if the specified collection is - * modified while the operation is in progress. - * - * <p>This implementation iterates over the specified collection, - * and adds each element returned by the iterator to this - * queue, in turn. A runtime exception encountered while - * trying to add an element (including, in particular, a - * <tt>null</tt> element) may result in only some of the elements - * having been successfully added when the associated exception is - * thrown. - * - * @param c collection containing elements to be added to this queue - * @return <tt>true</tt> if this queue changed as a result of the call - * @throws ClassCastException if the class of an element of the specified - * collection prevents it from being added to this queue - * @throws NullPointerException if the specified collection contains a - * null element and this queue does not permit null elements, - * or if the specified collection is null - * @throws IllegalArgumentException if some property of an element of the - * specified collection prevents it from being added to this - * queue, or if the specified collection is this queue - * @throws IllegalStateException if not all the elements can be added at - * this time due to insertion restrictions - * @see #add(Object) - */ - public boolean addAll(Collection<? extends E> c) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - boolean modified = false; - Iterator<? extends E> e = c.iterator(); - while (e.hasNext()) { - if (add(e.next())) - modified = true; - } - return modified; - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/ArrayDeque.java b/libjava/classpath/external/jsr166/java/util/ArrayDeque.java deleted file mode 100644 index a4bc75c..0000000 --- a/libjava/classpath/external/jsr166/java/util/ArrayDeque.java +++ /dev/null @@ -1,839 +0,0 @@ -/* - * Written by Josh Bloch of Google Inc. and released to the public domain, - * as explained at http://creativecommons.org/licenses/publicdomain. - */ - -package java.util; -import java.io.*; - -/** - * Resizable-array implementation of the {@link Deque} interface. Array - * deques have no capacity restrictions; they grow as necessary to support - * usage. They are not thread-safe; in the absence of external - * synchronization, they do not support concurrent access by multiple threads. - * Null elements are prohibited. This class is likely to be faster than - * {@link Stack} when used as a stack, and faster than {@link LinkedList} - * when used as a queue. - * - * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time. - * Exceptions include {@link #remove(Object) remove}, {@link - * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence - * removeLastOccurrence}, {@link #contains contains}, {@link #iterator - * iterator.remove()}, and the bulk operations, all of which run in linear - * time. - * - * <p>The iterators returned by this class's <tt>iterator</tt> method are - * <i>fail-fast</i>: If the deque is modified at any time after the iterator - * is created, in any way except through the iterator's own <tt>remove</tt> - * method, the iterator will generally throw a {@link - * ConcurrentModificationException}. Thus, in the face of concurrent - * modification, the iterator fails quickly and cleanly, rather than risking - * arbitrary, non-deterministic behavior at an undetermined time in the - * future. - * - * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed - * as it is, generally speaking, impossible to make any hard guarantees in the - * presence of unsynchronized concurrent modification. Fail-fast iterators - * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. - * Therefore, it would be wrong to write a program that depended on this - * exception for its correctness: <i>the fail-fast behavior of iterators - * should be used only to detect bugs.</i> - * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @author Josh Bloch and Doug Lea - * @since 1.6 - * @param <E> the type of elements held in this collection - */ -public class ArrayDeque<E> extends AbstractCollection<E> - implements Deque<E>, Cloneable, Serializable -{ - /** - * The array in which the elements of the deque are stored. - * The capacity of the deque is the length of this array, which is - * always a power of two. The array is never allowed to become - * full, except transiently within an addX method where it is - * resized (see doubleCapacity) immediately upon becoming full, - * thus avoiding head and tail wrapping around to equal each - * other. We also guarantee that all array cells not holding - * deque elements are always null. - */ - private transient E[] elements; - - /** - * The index of the element at the head of the deque (which is the - * element that would be removed by remove() or pop()); or an - * arbitrary number equal to tail if the deque is empty. - */ - private transient int head; - - /** - * The index at which the next element would be added to the tail - * of the deque (via addLast(E), add(E), or push(E)). - */ - private transient int tail; - - /** - * The minimum capacity that we'll use for a newly created deque. - * Must be a power of 2. - */ - private static final int MIN_INITIAL_CAPACITY = 8; - - // ****** Array allocation and resizing utilities ****** - - /** - * Allocate empty array to hold the given number of elements. - * - * @param numElements the number of elements to hold - */ - private void allocateElements(int numElements) { - int initialCapacity = MIN_INITIAL_CAPACITY; - // Find the best power of two to hold elements. - // Tests "<=" because arrays aren't kept full. - if (numElements >= initialCapacity) { - initialCapacity = numElements; - initialCapacity |= (initialCapacity >>> 1); - initialCapacity |= (initialCapacity >>> 2); - initialCapacity |= (initialCapacity >>> 4); - initialCapacity |= (initialCapacity >>> 8); - initialCapacity |= (initialCapacity >>> 16); - initialCapacity++; - - if (initialCapacity < 0) // Too many elements, must back off - initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements - } - elements = (E[]) new Object[initialCapacity]; - } - - /** - * Double the capacity of this deque. Call only when full, i.e., - * when head and tail have wrapped around to become equal. - */ - private void doubleCapacity() { - assert head == tail; - int p = head; - int n = elements.length; - int r = n - p; // number of elements to the right of p - int newCapacity = n << 1; - if (newCapacity < 0) - throw new IllegalStateException("Sorry, deque too big"); - Object[] a = new Object[newCapacity]; - System.arraycopy(elements, p, a, 0, r); - System.arraycopy(elements, 0, a, r, p); - elements = (E[])a; - head = 0; - tail = n; - } - - /** - * Copies the elements from our element array into the specified array, - * in order (from first to last element in the deque). It is assumed - * that the array is large enough to hold all elements in the deque. - * - * @return its argument - */ - private <T> T[] copyElements(T[] a) { - if (head < tail) { - System.arraycopy(elements, head, a, 0, size()); - } else if (head > tail) { - int headPortionLen = elements.length - head; - System.arraycopy(elements, head, a, 0, headPortionLen); - System.arraycopy(elements, 0, a, headPortionLen, tail); - } - return a; - } - - /** - * Constructs an empty array deque with an initial capacity - * sufficient to hold 16 elements. - */ - public ArrayDeque() { - elements = (E[]) new Object[16]; - } - - /** - * Constructs an empty array deque with an initial capacity - * sufficient to hold the specified number of elements. - * - * @param numElements lower bound on initial capacity of the deque - */ - public ArrayDeque(int numElements) { - allocateElements(numElements); - } - - /** - * Constructs a deque containing the elements of the specified - * collection, in the order they are returned by the collection's - * iterator. (The first element returned by the collection's - * iterator becomes the first element, or <i>front</i> of the - * deque.) - * - * @param c the collection whose elements are to be placed into the deque - * @throws NullPointerException if the specified collection is null - */ - public ArrayDeque(Collection<? extends E> c) { - allocateElements(c.size()); - addAll(c); - } - - // The main insertion and extraction methods are addFirst, - // addLast, pollFirst, pollLast. The other methods are defined in - // terms of these. - - /** - * Inserts the specified element at the front of this deque. - * - * @param e the element to add - * @throws NullPointerException if the specified element is null - */ - public void addFirst(E e) { - if (e == null) - throw new NullPointerException(); - elements[head = (head - 1) & (elements.length - 1)] = e; - if (head == tail) - doubleCapacity(); - } - - /** - * Inserts the specified element at the end of this deque. - * - * <p>This method is equivalent to {@link #add}. - * - * @param e the element to add - * @throws NullPointerException if the specified element is null - */ - public void addLast(E e) { - if (e == null) - throw new NullPointerException(); - elements[tail] = e; - if ( (tail = (tail + 1) & (elements.length - 1)) == head) - doubleCapacity(); - } - - /** - * Inserts the specified element at the front of this deque. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Deque#offerFirst}) - * @throws NullPointerException if the specified element is null - */ - public boolean offerFirst(E e) { - addFirst(e); - return true; - } - - /** - * Inserts the specified element at the end of this deque. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Deque#offerLast}) - * @throws NullPointerException if the specified element is null - */ - public boolean offerLast(E e) { - addLast(e); - return true; - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E removeFirst() { - E x = pollFirst(); - if (x == null) - throw new NoSuchElementException(); - return x; - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E removeLast() { - E x = pollLast(); - if (x == null) - throw new NoSuchElementException(); - return x; - } - - public E pollFirst() { - int h = head; - E result = elements[h]; // Element is null if deque empty - if (result == null) - return null; - elements[h] = null; // Must null out slot - head = (h + 1) & (elements.length - 1); - return result; - } - - public E pollLast() { - int t = (tail - 1) & (elements.length - 1); - E result = elements[t]; - if (result == null) - return null; - elements[t] = null; - tail = t; - return result; - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E getFirst() { - E x = elements[head]; - if (x == null) - throw new NoSuchElementException(); - return x; - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E getLast() { - E x = elements[(tail - 1) & (elements.length - 1)]; - if (x == null) - throw new NoSuchElementException(); - return x; - } - - public E peekFirst() { - return elements[head]; // elements[head] is null if deque empty - } - - public E peekLast() { - return elements[(tail - 1) & (elements.length - 1)]; - } - - /** - * Removes the first occurrence of the specified element in this - * deque (when traversing the deque from head to tail). - * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that - * <tt>o.equals(e)</tt> (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if the deque contained the specified element - */ - public boolean removeFirstOccurrence(Object o) { - if (o == null) - return false; - int mask = elements.length - 1; - int i = head; - E x; - while ( (x = elements[i]) != null) { - if (o.equals(x)) { - delete(i); - return true; - } - i = (i + 1) & mask; - } - return false; - } - - /** - * Removes the last occurrence of the specified element in this - * deque (when traversing the deque from head to tail). - * If the deque does not contain the element, it is unchanged. - * More formally, removes the last element <tt>e</tt> such that - * <tt>o.equals(e)</tt> (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if the deque contained the specified element - */ - public boolean removeLastOccurrence(Object o) { - if (o == null) - return false; - int mask = elements.length - 1; - int i = (tail - 1) & mask; - E x; - while ( (x = elements[i]) != null) { - if (o.equals(x)) { - delete(i); - return true; - } - i = (i - 1) & mask; - } - return false; - } - - // *** Queue methods *** - - /** - * Inserts the specified element at the end of this deque. - * - * <p>This method is equivalent to {@link #addLast}. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws NullPointerException if the specified element is null - */ - public boolean add(E e) { - addLast(e); - return true; - } - - /** - * Inserts the specified element at the end of this deque. - * - * <p>This method is equivalent to {@link #offerLast}. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Queue#offer}) - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e) { - return offerLast(e); - } - - /** - * Retrieves and removes the head of the queue represented by this deque. - * - * This method differs from {@link #poll poll} only in that it throws an - * exception if this deque is empty. - * - * <p>This method is equivalent to {@link #removeFirst}. - * - * @return the head of the queue represented by this deque - * @throws NoSuchElementException {@inheritDoc} - */ - public E remove() { - return removeFirst(); - } - - /** - * Retrieves and removes the head of the queue represented by this deque - * (in other words, the first element of this deque), or returns - * <tt>null</tt> if this deque is empty. - * - * <p>This method is equivalent to {@link #pollFirst}. - * - * @return the head of the queue represented by this deque, or - * <tt>null</tt> if this deque is empty - */ - public E poll() { - return pollFirst(); - } - - /** - * Retrieves, but does not remove, the head of the queue represented by - * this deque. This method differs from {@link #peek peek} only in - * that it throws an exception if this deque is empty. - * - * <p>This method is equivalent to {@link #getFirst}. - * - * @return the head of the queue represented by this deque - * @throws NoSuchElementException {@inheritDoc} - */ - public E element() { - return getFirst(); - } - - /** - * Retrieves, but does not remove, the head of the queue represented by - * this deque, or returns <tt>null</tt> if this deque is empty. - * - * <p>This method is equivalent to {@link #peekFirst}. - * - * @return the head of the queue represented by this deque, or - * <tt>null</tt> if this deque is empty - */ - public E peek() { - return peekFirst(); - } - - // *** Stack methods *** - - /** - * Pushes an element onto the stack represented by this deque. In other - * words, inserts the element at the front of this deque. - * - * <p>This method is equivalent to {@link #addFirst}. - * - * @param e the element to push - * @throws NullPointerException if the specified element is null - */ - public void push(E e) { - addFirst(e); - } - - /** - * Pops an element from the stack represented by this deque. In other - * words, removes and returns the first element of this deque. - * - * <p>This method is equivalent to {@link #removeFirst()}. - * - * @return the element at the front of this deque (which is the top - * of the stack represented by this deque) - * @throws NoSuchElementException {@inheritDoc} - */ - public E pop() { - return removeFirst(); - } - - private void checkInvariants() { - assert elements[tail] == null; - assert head == tail ? elements[head] == null : - (elements[head] != null && - elements[(tail - 1) & (elements.length - 1)] != null); - assert elements[(head - 1) & (elements.length - 1)] == null; - } - - /** - * Removes the element at the specified position in the elements array, - * adjusting head and tail as necessary. This can result in motion of - * elements backwards or forwards in the array. - * - * <p>This method is called delete rather than remove to emphasize - * that its semantics differ from those of {@link List#remove(int)}. - * - * @return true if elements moved backwards - */ - private boolean delete(int i) { - checkInvariants(); - final E[] elements = this.elements; - final int mask = elements.length - 1; - final int h = head; - final int t = tail; - final int front = (i - h) & mask; - final int back = (t - i) & mask; - - // Invariant: head <= i < tail mod circularity - if (front >= ((t - h) & mask)) - throw new ConcurrentModificationException(); - - // Optimize for least element motion - if (front < back) { - if (h <= i) { - System.arraycopy(elements, h, elements, h + 1, front); - } else { // Wrap around - System.arraycopy(elements, 0, elements, 1, i); - elements[0] = elements[mask]; - System.arraycopy(elements, h, elements, h + 1, mask - h); - } - elements[h] = null; - head = (h + 1) & mask; - return false; - } else { - if (i < t) { // Copy the null tail as well - System.arraycopy(elements, i + 1, elements, i, back); - tail = t - 1; - } else { // Wrap around - System.arraycopy(elements, i + 1, elements, i, mask - i); - elements[mask] = elements[0]; - System.arraycopy(elements, 1, elements, 0, t); - tail = (t - 1) & mask; - } - return true; - } - } - - // *** Collection Methods *** - - /** - * Returns the number of elements in this deque. - * - * @return the number of elements in this deque - */ - public int size() { - return (tail - head) & (elements.length - 1); - } - - /** - * Returns <tt>true</tt> if this deque contains no elements. - * - * @return <tt>true</tt> if this deque contains no elements - */ - public boolean isEmpty() { - return head == tail; - } - - /** - * Returns an iterator over the elements in this deque. The elements - * will be ordered from first (head) to last (tail). This is the same - * order that elements would be dequeued (via successive calls to - * {@link #remove} or popped (via successive calls to {@link #pop}). - * - * @return an iterator over the elements in this deque - */ - public Iterator<E> iterator() { - return new DeqIterator(); - } - - public Iterator<E> descendingIterator() { - return new DescendingIterator(); - } - - private class DeqIterator implements Iterator<E> { - /** - * Index of element to be returned by subsequent call to next. - */ - private int cursor = head; - - /** - * Tail recorded at construction (also in remove), to stop - * iterator and also to check for comodification. - */ - private int fence = tail; - - /** - * Index of element returned by most recent call to next. - * Reset to -1 if element is deleted by a call to remove. - */ - private int lastRet = -1; - - public boolean hasNext() { - return cursor != fence; - } - - public E next() { - if (cursor == fence) - throw new NoSuchElementException(); - E result = elements[cursor]; - // This check doesn't catch all possible comodifications, - // but does catch the ones that corrupt traversal - if (tail != fence || result == null) - throw new ConcurrentModificationException(); - lastRet = cursor; - cursor = (cursor + 1) & (elements.length - 1); - return result; - } - - public void remove() { - if (lastRet < 0) - throw new IllegalStateException(); - if (delete(lastRet)) { // if left-shifted, undo increment in next() - cursor = (cursor - 1) & (elements.length - 1); - fence = tail; - } - lastRet = -1; - } - } - - private class DescendingIterator implements Iterator<E> { - /* - * This class is nearly a mirror-image of DeqIterator, using - * tail instead of head for initial cursor, and head instead of - * tail for fence. - */ - private int cursor = tail; - private int fence = head; - private int lastRet = -1; - - public boolean hasNext() { - return cursor != fence; - } - - public E next() { - if (cursor == fence) - throw new NoSuchElementException(); - cursor = (cursor - 1) & (elements.length - 1); - E result = elements[cursor]; - if (head != fence || result == null) - throw new ConcurrentModificationException(); - lastRet = cursor; - return result; - } - - public void remove() { - if (lastRet < 0) - throw new IllegalStateException(); - if (!delete(lastRet)) { - cursor = (cursor + 1) & (elements.length - 1); - fence = head; - } - lastRet = -1; - } - } - - /** - * Returns <tt>true</tt> if this deque contains the specified element. - * More formally, returns <tt>true</tt> if and only if this deque contains - * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. - * - * @param o object to be checked for containment in this deque - * @return <tt>true</tt> if this deque contains the specified element - */ - public boolean contains(Object o) { - if (o == null) - return false; - int mask = elements.length - 1; - int i = head; - E x; - while ( (x = elements[i]) != null) { - if (o.equals(x)) - return true; - i = (i + 1) & mask; - } - return false; - } - - /** - * Removes a single instance of the specified element from this deque. - * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that - * <tt>o.equals(e)</tt> (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * <p>This method is equivalent to {@link #removeFirstOccurrence}. - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if this deque contained the specified element - */ - public boolean remove(Object o) { - return removeFirstOccurrence(o); - } - - /** - * Removes all of the elements from this deque. - * The deque will be empty after this call returns. - */ - public void clear() { - int h = head; - int t = tail; - if (h != t) { // clear all cells - head = tail = 0; - int i = h; - int mask = elements.length - 1; - do { - elements[i] = null; - i = (i + 1) & mask; - } while (i != t); - } - } - - /** - * Returns an array containing all of the elements in this deque - * in proper sequence (from first to last element). - * - * <p>The returned array will be "safe" in that no references to it are - * maintained by this deque. (In other words, this method must allocate - * a new array). The caller is thus free to modify the returned array. - * - * <p>This method acts as bridge between array-based and collection-based - * APIs. - * - * @return an array containing all of the elements in this deque - */ - public Object[] toArray() { - return copyElements(new Object[size()]); - } - - /** - * Returns an array containing all of the elements in this deque in - * proper sequence (from first to last element); the runtime type of the - * returned array is that of the specified array. If the deque fits in - * the specified array, it is returned therein. Otherwise, a new array - * is allocated with the runtime type of the specified array and the - * size of this deque. - * - * <p>If this deque fits in the specified array with room to spare - * (i.e., the array has more elements than this deque), the element in - * the array immediately following the end of the deque is set to - * <tt>null</tt>. - * - * <p>Like the {@link #toArray()} method, this method acts as bridge between - * array-based and collection-based APIs. Further, this method allows - * precise control over the runtime type of the output array, and may, - * under certain circumstances, be used to save allocation costs. - * - * <p>Suppose <tt>x</tt> is a deque known to contain only strings. - * The following code can be used to dump the deque into a newly - * allocated array of <tt>String</tt>: - * - * <pre> - * String[] y = x.toArray(new String[0]);</pre> - * - * Note that <tt>toArray(new Object[0])</tt> is identical in function to - * <tt>toArray()</tt>. - * - * @param a the array into which the elements of the deque are to - * be stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose - * @return an array containing all of the elements in this deque - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in - * this deque - * @throws NullPointerException if the specified array is null - */ - public <T> T[] toArray(T[] a) { - int size = size(); - if (a.length < size) - a = (T[])java.lang.reflect.Array.newInstance( - a.getClass().getComponentType(), size); - copyElements(a); - if (a.length > size) - a[size] = null; - return a; - } - - // *** Object methods *** - - /** - * Returns a copy of this deque. - * - * @return a copy of this deque - */ - public ArrayDeque<E> clone() { - try { - ArrayDeque<E> result = (ArrayDeque<E>) super.clone(); - // Classpath local: we don't have Arrays.copyOf yet. - // result.elements = Arrays.copyOf(elements, elements.length); - result.elements = (E[]) elements.clone(); - return result; - - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } - - /** - * Appease the serialization gods. - */ - private static final long serialVersionUID = 2340985798034038923L; - - /** - * Serialize this deque. - * - * @serialData The current size (<tt>int</tt>) of the deque, - * followed by all of its elements (each an object reference) in - * first-to-last order. - */ - private void writeObject(ObjectOutputStream s) throws IOException { - s.defaultWriteObject(); - - // Write out size - s.writeInt(size()); - - // Write out elements in order. - int mask = elements.length - 1; - for (int i = head; i != tail; i = (i + 1) & mask) - s.writeObject(elements[i]); - } - - /** - * Deserialize this deque. - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject(); - - // Read in size and allocate array - int size = s.readInt(); - allocateElements(size); - head = 0; - tail = size; - - // Read in all elements in the proper order. - for (int i = 0; i < size; i++) - elements[i] = (E)s.readObject(); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/Deque.java b/libjava/classpath/external/jsr166/java/util/Deque.java deleted file mode 100644 index a769561..0000000 --- a/libjava/classpath/external/jsr166/java/util/Deque.java +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Written by Doug Lea and Josh Bloch with assistance from members of - * JCP JSR-166 Expert Group and released to the public domain, as explained - * at http://creativecommons.org/licenses/publicdomain - */ - -package java.util; - -/** - * A linear collection that supports element insertion and removal at - * both ends. The name <i>deque</i> is short for "double ended queue" - * and is usually pronounced "deck". Most <tt>Deque</tt> - * implementations place no fixed limits on the number of elements - * they may contain, but this interface supports capacity-restricted - * deques as well as those with no fixed size limit. - * - * <p>This interface defines methods to access the elements at both - * ends of the deque. Methods are provided to insert, remove, and - * examine the element. Each of these methods exists in two forms: - * one throws an exception if the operation fails, the other returns a - * special value (either <tt>null</tt> or <tt>false</tt>, depending on - * the operation). The latter form of the insert operation is - * designed specifically for use with capacity-restricted - * <tt>Deque</tt> implementations; in most implementations, insert - * operations cannot fail. - * - * <p>The twelve methods described above are summarized in the - * following table: - * - * <p> - * <table BORDER CELLPADDING=3 CELLSPACING=1> - * <tr> - * <td></td> - * <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td> - * <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td> - * </tr> - * <tr> - * <td></td> - * <td ALIGN=CENTER><em>Throws exception</em></td> - * <td ALIGN=CENTER><em>Special value</em></td> - * <td ALIGN=CENTER><em>Throws exception</em></td> - * <td ALIGN=CENTER><em>Special value</em></td> - * </tr> - * <tr> - * <td><b>Insert</b></td> - * <td>{@link #addFirst addFirst(e)}</td> - * <td>{@link #offerFirst offerFirst(e)}</td> - * <td>{@link #addLast addLast(e)}</td> - * <td>{@link #offerLast offerLast(e)}</td> - * </tr> - * <tr> - * <td><b>Remove</b></td> - * <td>{@link #removeFirst removeFirst()}</td> - * <td>{@link #pollFirst pollFirst()}</td> - * <td>{@link #removeLast removeLast()}</td> - * <td>{@link #pollLast pollLast()}</td> - * </tr> - * <tr> - * <td><b>Examine</b></td> - * <td>{@link #getFirst getFirst()}</td> - * <td>{@link #peekFirst peekFirst()}</td> - * <td>{@link #getLast getLast()}</td> - * <td>{@link #peekLast peekLast()}</td> - * </tr> - * </table> - * - * <p>This interface extends the {@link Queue} interface. When a deque is - * used as a queue, FIFO (First-In-First-Out) behavior results. Elements are - * added at the end of the deque and removed from the beginning. The methods - * inherited from the <tt>Queue</tt> interface are precisely equivalent to - * <tt>Deque</tt> methods as indicated in the following table: - * - * <p> - * <table BORDER CELLPADDING=3 CELLSPACING=1> - * <tr> - * <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td> - * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td> - * </tr> - * <tr> - * <td>{@link java.util.Queue#add add(e)}</td> - * <td>{@link #addLast addLast(e)}</td> - * </tr> - * <tr> - * <td>{@link java.util.Queue#offer offer(e)}</td> - * <td>{@link #offerLast offerLast(e)}</td> - * </tr> - * <tr> - * <td>{@link java.util.Queue#remove remove()}</td> - * <td>{@link #removeFirst removeFirst()}</td> - * </tr> - * <tr> - * <td>{@link java.util.Queue#poll poll()}</td> - * <td>{@link #pollFirst pollFirst()}</td> - * </tr> - * <tr> - * <td>{@link java.util.Queue#element element()}</td> - * <td>{@link #getFirst getFirst()}</td> - * </tr> - * <tr> - * <td>{@link java.util.Queue#peek peek()}</td> - * <td>{@link #peek peekFirst()}</td> - * </tr> - * </table> - * - * <p>Deques can also be used as LIFO (Last-In-First-Out) stacks. This - * interface should be used in preference to the legacy {@link Stack} class. - * When a deque is used as a stack, elements are pushed and popped from the - * beginning of the deque. Stack methods are precisely equivalent to - * <tt>Deque</tt> methods as indicated in the table below: - * - * <p> - * <table BORDER CELLPADDING=3 CELLSPACING=1> - * <tr> - * <td ALIGN=CENTER> <b>Stack Method</b></td> - * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td> - * </tr> - * <tr> - * <td>{@link #push push(e)}</td> - * <td>{@link #addFirst addFirst(e)}</td> - * </tr> - * <tr> - * <td>{@link #pop pop()}</td> - * <td>{@link #removeFirst removeFirst()}</td> - * </tr> - * <tr> - * <td>{@link #peek peek()}</td> - * <td>{@link #peekFirst peekFirst()}</td> - * </tr> - * </table> - * - * <p>Note that the {@link #peek peek} method works equally well when - * a deque is used as a queue or a stack; in either case, elements are - * drawn from the beginning of the deque. - * - * <p>This interface provides two methods to remove interior - * elements, {@link #removeFirstOccurrence removeFirstOccurrence} and - * {@link #removeLastOccurrence removeLastOccurrence}. - * - * <p>Unlike the {@link List} interface, this interface does not - * provide support for indexed access to elements. - * - * <p>While <tt>Deque</tt> implementations are not strictly required - * to prohibit the insertion of null elements, they are strongly - * encouraged to do so. Users of any <tt>Deque</tt> implementations - * that do allow null elements are strongly encouraged <i>not</i> to - * take advantage of the ability to insert nulls. This is so because - * <tt>null</tt> is used as a special return value by various methods - * to indicated that the deque is empty. - * - * <p><tt>Deque</tt> implementations generally do not define - * element-based versions of the <tt>equals</tt> and <tt>hashCode</tt> - * methods, but instead inherit the identity-based versions from class - * <tt>Object</tt>. - * - * <p>This interface is a member of the <a - * href="{@docRoot}/../technotes/guides/collections/index.html"> Java Collections - * Framework</a>. - * - * @author Doug Lea - * @author Josh Bloch - * @since 1.6 - * @param <E> the type of elements held in this collection - */ - -public interface Deque<E> extends Queue<E> { - /** - * Inserts the specified element at the front of this deque if it is - * possible to do so immediately without violating capacity restrictions. - * When using a capacity-restricted deque, it is generally preferable to - * use method {@link #offerFirst}. - * - * @param e the element to add - * @throws IllegalStateException if the element cannot be added at this - * time due to capacity restrictions - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - void addFirst(E e); - - /** - * Inserts the specified element at the end of this deque if it is - * possible to do so immediately without violating capacity restrictions. - * When using a capacity-restricted deque, it is generally preferable to - * use method {@link #offerLast}. - * - * <p>This method is equivalent to {@link #add}. - * - * @param e the element to add - * @throws IllegalStateException if the element cannot be added at this - * time due to capacity restrictions - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - void addLast(E e); - - /** - * Inserts the specified element at the front of this deque unless it would - * violate capacity restrictions. When using a capacity-restricted deque, - * this method is generally preferable to the {@link #addFirst} method, - * which can fail to insert an element only by throwing an exception. - * - * @param e the element to add - * @return <tt>true</tt> if the element was added to this deque, else - * <tt>false</tt> - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean offerFirst(E e); - - /** - * Inserts the specified element at the end of this deque unless it would - * violate capacity restrictions. When using a capacity-restricted deque, - * this method is generally preferable to the {@link #addLast} method, - * which can fail to insert an element only by throwing an exception. - * - * @param e the element to add - * @return <tt>true</tt> if the element was added to this deque, else - * <tt>false</tt> - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean offerLast(E e); - - /** - * Retrieves and removes the first element of this deque. This method - * differs from {@link #pollFirst pollFirst} only in that it throws an - * exception if this deque is empty. - * - * @return the head of this deque - * @throws NoSuchElementException if this deque is empty - */ - E removeFirst(); - - /** - * Retrieves and removes the last element of this deque. This method - * differs from {@link #pollLast pollLast} only in that it throws an - * exception if this deque is empty. - * - * @return the tail of this deque - * @throws NoSuchElementException if this deque is empty - */ - E removeLast(); - - /** - * Retrieves and removes the first element of this deque, - * or returns <tt>null</tt> if this deque is empty. - * - * @return the head of this deque, or <tt>null</tt> if this deque is empty - */ - E pollFirst(); - - /** - * Retrieves and removes the last element of this deque, - * or returns <tt>null</tt> if this deque is empty. - * - * @return the tail of this deque, or <tt>null</tt> if this deque is empty - */ - E pollLast(); - - /** - * Retrieves, but does not remove, the first element of this deque. - * - * This method differs from {@link #peekFirst peekFirst} only in that it - * throws an exception if this deque is empty. - * - * @return the head of this deque - * @throws NoSuchElementException if this deque is empty - */ - E getFirst(); - - /** - * Retrieves, but does not remove, the last element of this deque. - * This method differs from {@link #peekLast peekLast} only in that it - * throws an exception if this deque is empty. - * - * @return the tail of this deque - * @throws NoSuchElementException if this deque is empty - */ - E getLast(); - - /** - * Retrieves, but does not remove, the first element of this deque, - * or returns <tt>null</tt> if this deque is empty. - * - * @return the head of this deque, or <tt>null</tt> if this deque is empty - */ - E peekFirst(); - - /** - * Retrieves, but does not remove, the last element of this deque, - * or returns <tt>null</tt> if this deque is empty. - * - * @return the tail of this deque, or <tt>null</tt> if this deque is empty - */ - E peekLast(); - - /** - * Removes the first occurrence of the specified element from this deque. - * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that - * <tt>(o==null ? e==null : o.equals(e))</tt> - * (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if an element was removed as a result of this call - * @throws ClassCastException if the class of the specified element - * is incompatible with this deque (optional) - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements (optional) - */ - boolean removeFirstOccurrence(Object o); - - /** - * Removes the last occurrence of the specified element from this deque. - * If the deque does not contain the element, it is unchanged. - * More formally, removes the last element <tt>e</tt> such that - * <tt>(o==null ? e==null : o.equals(e))</tt> - * (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if an element was removed as a result of this call - * @throws ClassCastException if the class of the specified element - * is incompatible with this deque (optional) - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements (optional) - */ - boolean removeLastOccurrence(Object o); - - // *** Queue methods *** - - /** - * Inserts the specified element into the queue represented by this deque - * (in other words, at the tail of this deque) if it is possible to do so - * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an - * <tt>IllegalStateException</tt> if no space is currently available. - * When using a capacity-restricted deque, it is generally preferable to - * use {@link #offer(Object) offer}. - * - * <p>This method is equivalent to {@link #addLast}. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws IllegalStateException if the element cannot be added at this - * time due to capacity restrictions - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean add(E e); - - /** - * Inserts the specified element into the queue represented by this deque - * (in other words, at the tail of this deque) if it is possible to do so - * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and <tt>false</tt> if no space is currently - * available. When using a capacity-restricted deque, this method is - * generally preferable to the {@link #add} method, which can fail to - * insert an element only by throwing an exception. - * - * <p>This method is equivalent to {@link #offerLast}. - * - * @param e the element to add - * @return <tt>true</tt> if the element was added to this deque, else - * <tt>false</tt> - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean offer(E e); - - /** - * Retrieves and removes the head of the queue represented by this deque - * (in other words, the first element of this deque). - * This method differs from {@link #poll poll} only in that it throws an - * exception if this deque is empty. - * - * <p>This method is equivalent to {@link #removeFirst()}. - * - * @return the head of the queue represented by this deque - * @throws NoSuchElementException if this deque is empty - */ - E remove(); - - /** - * Retrieves and removes the head of the queue represented by this deque - * (in other words, the first element of this deque), or returns - * <tt>null</tt> if this deque is empty. - * - * <p>This method is equivalent to {@link #pollFirst()}. - * - * @return the first element of this deque, or <tt>null</tt> if - * this deque is empty - */ - E poll(); - - /** - * Retrieves, but does not remove, the head of the queue represented by - * this deque (in other words, the first element of this deque). - * This method differs from {@link #peek peek} only in that it throws an - * exception if this deque is empty. - * - * <p>This method is equivalent to {@link #getFirst()}. - * - * @return the head of the queue represented by this deque - * @throws NoSuchElementException if this deque is empty - */ - E element(); - - /** - * Retrieves, but does not remove, the head of the queue represented by - * this deque (in other words, the first element of this deque), or - * returns <tt>null</tt> if this deque is empty. - * - * <p>This method is equivalent to {@link #peekFirst()}. - * - * @return the head of the queue represented by this deque, or - * <tt>null</tt> if this deque is empty - */ - E peek(); - - - // *** Stack methods *** - - /** - * Pushes an element onto the stack represented by this deque (in other - * words, at the head of this deque) if it is possible to do so - * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an - * <tt>IllegalStateException</tt> if no space is currently available. - * - * <p>This method is equivalent to {@link #addFirst}. - * - * @param e the element to push - * @throws IllegalStateException if the element cannot be added at this - * time due to capacity restrictions - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - void push(E e); - - /** - * Pops an element from the stack represented by this deque. In other - * words, removes and returns the first element of this deque. - * - * <p>This method is equivalent to {@link #removeFirst()}. - * - * @return the element at the front of this deque (which is the top - * of the stack represented by this deque) - * @throws NoSuchElementException if this deque is empty - */ - E pop(); - - - // *** Collection methods *** - - /** - * Removes the first occurrence of the specified element from this deque. - * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that - * <tt>(o==null ? e==null : o.equals(e))</tt> - * (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * <p>This method is equivalent to {@link #removeFirstOccurrence}. - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if an element was removed as a result of this call - * @throws ClassCastException if the class of the specified element - * is incompatible with this deque (optional) - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements (optional) - */ - boolean remove(Object o); - - /** - * Returns <tt>true</tt> if this deque contains the specified element. - * More formally, returns <tt>true</tt> if and only if this deque contains - * at least one element <tt>e</tt> such that - * <tt>(o==null ? e==null : o.equals(e))</tt>. - * - * @param o element whose presence in this deque is to be tested - * @return <tt>true</tt> if this deque contains the specified element - * @throws ClassCastException if the type of the specified element - * is incompatible with this deque (optional) - * @throws NullPointerException if the specified element is null and this - * deque does not permit null elements (optional) - */ - boolean contains(Object o); - - /** - * Returns the number of elements in this deque. - * - * @return the number of elements in this deque - */ - public int size(); - - /** - * Returns an iterator over the elements in this deque in proper sequence. - * The elements will be returned in order from first (head) to last (tail). - * - * @return an iterator over the elements in this deque in proper sequence - */ - Iterator<E> iterator(); - - /** - * Returns an iterator over the elements in this deque in reverse - * sequential order. The elements will be returned in order from - * last (tail) to first (head). - * - * @return an iterator over the elements in this deque in reverse - * sequence - */ - Iterator<E> descendingIterator(); - -} diff --git a/libjava/classpath/external/jsr166/java/util/NavigableMap.java b/libjava/classpath/external/jsr166/java/util/NavigableMap.java deleted file mode 100644 index a55f84b..0000000 --- a/libjava/classpath/external/jsr166/java/util/NavigableMap.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Written by Doug Lea and Josh Bloch with assistance from members of JCP - * JSR-166 Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util; - -/** - * A {@link SortedMap} extended with navigation methods returning the - * closest matches for given search targets. Methods - * {@code lowerEntry}, {@code floorEntry}, {@code ceilingEntry}, - * and {@code higherEntry} return {@code Map.Entry} objects - * associated with keys respectively less than, less than or equal, - * greater than or equal, and greater than a given key, returning - * {@code null} if there is no such key. Similarly, methods - * {@code lowerKey}, {@code floorKey}, {@code ceilingKey}, and - * {@code higherKey} return only the associated keys. All of these - * methods are designed for locating, not traversing entries. - * - * <p>A {@code NavigableMap} may be accessed and traversed in either - * ascending or descending key order. The {@code descendingMap} - * method returns a view of the map with the senses of all relational - * and directional methods inverted. The performance of ascending - * operations and views is likely to be faster than that of descending - * ones. Methods {@code subMap}, {@code headMap}, - * and {@code tailMap} differ from the like-named {@code - * SortedMap} methods in accepting additional arguments describing - * whether lower and upper bounds are inclusive versus exclusive. - * Submaps of any {@code NavigableMap} must implement the {@code - * NavigableMap} interface. - * - * <p>This interface additionally defines methods {@code firstEntry}, - * {@code pollFirstEntry}, {@code lastEntry}, and - * {@code pollLastEntry} that return and/or remove the least and - * greatest mappings, if any exist, else returning {@code null}. - * - * <p>Implementations of entry-returning methods are expected to - * return {@code Map.Entry} pairs representing snapshots of mappings - * at the time they were produced, and thus generally do <em>not</em> - * support the optional {@code Entry.setValue} method. Note however - * that it is possible to change mappings in the associated map using - * method {@code put}. - * - * <p>Methods - * {@link #subMap(Object, Object) subMap(K, K)}, - * {@link #headMap(Object) headMap(K)}, and - * {@link #tailMap(Object) tailMap(K)} - * are specified to return {@code SortedMap} to allow existing - * implementations of {@code SortedMap} to be compatibly retrofitted to - * implement {@code NavigableMap}, but extensions and implementations - * of this interface are encouraged to override these methods to return - * {@code NavigableMap}. Similarly, - * {@link #keySet()} can be overriden to return {@code NavigableSet}. - * - * <p>This interface is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @author Doug Lea - * @author Josh Bloch - * @param <K> the type of keys maintained by this map - * @param <V> the type of mapped values - * @since 1.6 - */ -public interface NavigableMap<K,V> extends SortedMap<K,V> { - /** - * Returns a key-value mapping associated with the greatest key - * strictly less than the given key, or {@code null} if there is - * no such key. - * - * @param key the key - * @return an entry with the greatest key less than {@code key}, - * or {@code null} if there is no such key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - * and this map does not permit null keys - */ - Map.Entry<K,V> lowerEntry(K key); - - /** - * Returns the greatest key strictly less than the given key, or - * {@code null} if there is no such key. - * - * @param key the key - * @return the greatest key less than {@code key}, - * or {@code null} if there is no such key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - * and this map does not permit null keys - */ - K lowerKey(K key); - - /** - * Returns a key-value mapping associated with the greatest key - * less than or equal to the given key, or {@code null} if there - * is no such key. - * - * @param key the key - * @return an entry with the greatest key less than or equal to - * {@code key}, or {@code null} if there is no such key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - * and this map does not permit null keys - */ - Map.Entry<K,V> floorEntry(K key); - - /** - * Returns the greatest key less than or equal to the given key, - * or {@code null} if there is no such key. - * - * @param key the key - * @return the greatest key less than or equal to {@code key}, - * or {@code null} if there is no such key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - * and this map does not permit null keys - */ - K floorKey(K key); - - /** - * Returns a key-value mapping associated with the least key - * greater than or equal to the given key, or {@code null} if - * there is no such key. - * - * @param key the key - * @return an entry with the least key greater than or equal to - * {@code key}, or {@code null} if there is no such key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - * and this map does not permit null keys - */ - Map.Entry<K,V> ceilingEntry(K key); - - /** - * Returns the least key greater than or equal to the given key, - * or {@code null} if there is no such key. - * - * @param key the key - * @return the least key greater than or equal to {@code key}, - * or {@code null} if there is no such key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - * and this map does not permit null keys - */ - K ceilingKey(K key); - - /** - * Returns a key-value mapping associated with the least key - * strictly greater than the given key, or {@code null} if there - * is no such key. - * - * @param key the key - * @return an entry with the least key greater than {@code key}, - * or {@code null} if there is no such key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - * and this map does not permit null keys - */ - Map.Entry<K,V> higherEntry(K key); - - /** - * Returns the least key strictly greater than the given key, or - * {@code null} if there is no such key. - * - * @param key the key - * @return the least key greater than {@code key}, - * or {@code null} if there is no such key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - * and this map does not permit null keys - */ - K higherKey(K key); - - /** - * Returns a key-value mapping associated with the least - * key in this map, or {@code null} if the map is empty. - * - * @return an entry with the least key, - * or {@code null} if this map is empty - */ - Map.Entry<K,V> firstEntry(); - - /** - * Returns a key-value mapping associated with the greatest - * key in this map, or {@code null} if the map is empty. - * - * @return an entry with the greatest key, - * or {@code null} if this map is empty - */ - Map.Entry<K,V> lastEntry(); - - /** - * Removes and returns a key-value mapping associated with - * the least key in this map, or {@code null} if the map is empty. - * - * @return the removed first entry of this map, - * or {@code null} if this map is empty - */ - Map.Entry<K,V> pollFirstEntry(); - - /** - * Removes and returns a key-value mapping associated with - * the greatest key in this map, or {@code null} if the map is empty. - * - * @return the removed last entry of this map, - * or {@code null} if this map is empty - */ - Map.Entry<K,V> pollLastEntry(); - - /** - * Returns a reverse order view of the mappings contained in this map. - * The descending map is backed by this map, so changes to the map are - * reflected in the descending map, and vice-versa. If either map is - * modified while an iteration over a collection view of either map - * is in progress (except through the iterator's own {@code remove} - * operation), the results of the iteration are undefined. - * - * <p>The returned map has an ordering equivalent to - * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. - * The expression {@code m.descendingMap().descendingMap()} returns a - * view of {@code m} essentially equivalent to {@code m}. - * - * @return a reverse order view of this map - */ - NavigableMap<K,V> descendingMap(); - - /** - * Returns a {@link NavigableSet} view of the keys contained in this map. - * The set's iterator returns the keys in ascending order. - * The set is backed by the map, so changes to the map are reflected in - * the set, and vice-versa. If the map is modified while an iteration - * over the set is in progress (except through the iterator's own {@code - * remove} operation), the results of the iteration are undefined. The - * set supports element removal, which removes the corresponding mapping - * from the map, via the {@code Iterator.remove}, {@code Set.remove}, - * {@code removeAll}, {@code retainAll}, and {@code clear} operations. - * It does not support the {@code add} or {@code addAll} operations. - * - * @return a navigable set view of the keys in this map - */ - NavigableSet<K> navigableKeySet(); - - /** - * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. - * The set's iterator returns the keys in descending order. - * The set is backed by the map, so changes to the map are reflected in - * the set, and vice-versa. If the map is modified while an iteration - * over the set is in progress (except through the iterator's own {@code - * remove} operation), the results of the iteration are undefined. The - * set supports element removal, which removes the corresponding mapping - * from the map, via the {@code Iterator.remove}, {@code Set.remove}, - * {@code removeAll}, {@code retainAll}, and {@code clear} operations. - * It does not support the {@code add} or {@code addAll} operations. - * - * @return a reverse order navigable set view of the keys in this map - */ - NavigableSet<K> descendingKeySet(); - - /** - * Returns a view of the portion of this map whose keys range from - * {@code fromKey} to {@code toKey}. If {@code fromKey} and - * {@code toKey} are equal, the returned map is empty unless - * {@code fromExclusive} and {@code toExclusive} are both true. The - * returned map is backed by this map, so changes in the returned map are - * reflected in this map, and vice-versa. The returned map supports all - * optional map operations that this map supports. - * - * <p>The returned map will throw an {@code IllegalArgumentException} - * on an attempt to insert a key outside of its range, or to construct a - * submap either of whose endpoints lie outside its range. - * - * @param fromKey low endpoint of the keys in the returned map - * @param fromInclusive {@code true} if the low endpoint - * is to be included in the returned view - * @param toKey high endpoint of the keys in the returned map - * @param toInclusive {@code true} if the high endpoint - * is to be included in the returned view - * @return a view of the portion of this map whose keys range from - * {@code fromKey} to {@code toKey} - * @throws ClassCastException if {@code fromKey} and {@code toKey} - * cannot be compared to one another using this map's comparator - * (or, if the map has no comparator, using natural ordering). - * Implementations may, but are not required to, throw this - * exception if {@code fromKey} or {@code toKey} - * cannot be compared to keys currently in the map. - * @throws NullPointerException if {@code fromKey} or {@code toKey} - * is null and this map does not permit null keys - * @throws IllegalArgumentException if {@code fromKey} is greater than - * {@code toKey}; or if this map itself has a restricted - * range, and {@code fromKey} or {@code toKey} lies - * outside the bounds of the range - */ - NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, - K toKey, boolean toInclusive); - - /** - * Returns a view of the portion of this map whose keys are less than (or - * equal to, if {@code inclusive} is true) {@code toKey}. The returned - * map is backed by this map, so changes in the returned map are reflected - * in this map, and vice-versa. The returned map supports all optional - * map operations that this map supports. - * - * <p>The returned map will throw an {@code IllegalArgumentException} - * on an attempt to insert a key outside its range. - * - * @param toKey high endpoint of the keys in the returned map - * @param inclusive {@code true} if the high endpoint - * is to be included in the returned view - * @return a view of the portion of this map whose keys are less than - * (or equal to, if {@code inclusive} is true) {@code toKey} - * @throws ClassCastException if {@code toKey} is not compatible - * with this map's comparator (or, if the map has no comparator, - * if {@code toKey} does not implement {@link Comparable}). - * Implementations may, but are not required to, throw this - * exception if {@code toKey} cannot be compared to keys - * currently in the map. - * @throws NullPointerException if {@code toKey} is null - * and this map does not permit null keys - * @throws IllegalArgumentException if this map itself has a - * restricted range, and {@code toKey} lies outside the - * bounds of the range - */ - NavigableMap<K,V> headMap(K toKey, boolean inclusive); - - /** - * Returns a view of the portion of this map whose keys are greater than (or - * equal to, if {@code inclusive} is true) {@code fromKey}. The returned - * map is backed by this map, so changes in the returned map are reflected - * in this map, and vice-versa. The returned map supports all optional - * map operations that this map supports. - * - * <p>The returned map will throw an {@code IllegalArgumentException} - * on an attempt to insert a key outside its range. - * - * @param fromKey low endpoint of the keys in the returned map - * @param inclusive {@code true} if the low endpoint - * is to be included in the returned view - * @return a view of the portion of this map whose keys are greater than - * (or equal to, if {@code inclusive} is true) {@code fromKey} - * @throws ClassCastException if {@code fromKey} is not compatible - * with this map's comparator (or, if the map has no comparator, - * if {@code fromKey} does not implement {@link Comparable}). - * Implementations may, but are not required to, throw this - * exception if {@code fromKey} cannot be compared to keys - * currently in the map. - * @throws NullPointerException if {@code fromKey} is null - * and this map does not permit null keys - * @throws IllegalArgumentException if this map itself has a - * restricted range, and {@code fromKey} lies outside the - * bounds of the range - */ - NavigableMap<K,V> tailMap(K fromKey, boolean inclusive); - - /** - * {@inheritDoc} - * - * <p>Equivalent to {@code subMap(fromKey, true, toKey, false)}. - * - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - SortedMap<K,V> subMap(K fromKey, K toKey); - - /** - * {@inheritDoc} - * - * <p>Equivalent to {@code headMap(toKey, false)}. - * - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - SortedMap<K,V> headMap(K toKey); - - /** - * {@inheritDoc} - * - * <p>Equivalent to {@code tailMap(fromKey, true)}. - * - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - SortedMap<K,V> tailMap(K fromKey); -} diff --git a/libjava/classpath/external/jsr166/java/util/NavigableSet.java b/libjava/classpath/external/jsr166/java/util/NavigableSet.java deleted file mode 100644 index e14fe34..0000000 --- a/libjava/classpath/external/jsr166/java/util/NavigableSet.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Written by Doug Lea and Josh Bloch with assistance from members of JCP - * JSR-166 Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util; - -/** - * A {@link SortedSet} extended with navigation methods reporting - * closest matches for given search targets. Methods {@code lower}, - * {@code floor}, {@code ceiling}, and {@code higher} return elements - * respectively less than, less than or equal, greater than or equal, - * and greater than a given element, returning {@code null} if there - * is no such element. A {@code NavigableSet} may be accessed and - * traversed in either ascending or descending order. The {@code - * descendingSet} method returns a view of the set with the senses of - * all relational and directional methods inverted. The performance of - * ascending operations and views is likely to be faster than that of - * descending ones. This interface additionally defines methods - * {@code pollFirst} and {@code pollLast} that return and remove the - * lowest and highest element, if one exists, else returning {@code - * null}. Methods {@code subSet}, {@code headSet}, - * and {@code tailSet} differ from the like-named {@code - * SortedSet} methods in accepting additional arguments describing - * whether lower and upper bounds are inclusive versus exclusive. - * Subsets of any {@code NavigableSet} must implement the {@code - * NavigableSet} interface. - * - * <p> The return values of navigation methods may be ambiguous in - * implementations that permit {@code null} elements. However, even - * in this case the result can be disambiguated by checking - * {@code contains(null)}. To avoid such issues, implementations of - * this interface are encouraged to <em>not</em> permit insertion of - * {@code null} elements. (Note that sorted sets of {@link - * Comparable} elements intrinsically do not permit {@code null}.) - * - * <p>Methods - * {@link #subSet(Object, Object) subSet(E, E)}, - * {@link #headSet(Object) headSet(E)}, and - * {@link #tailSet(Object) tailSet(E)} - * are specified to return {@code SortedSet} to allow existing - * implementations of {@code SortedSet} to be compatibly retrofitted to - * implement {@code NavigableSet}, but extensions and implementations - * of this interface are encouraged to override these methods to return - * {@code NavigableSet}. - * - * <p>This interface is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @author Doug Lea - * @author Josh Bloch - * @param <E> the type of elements maintained by this set - * @since 1.6 - */ -public interface NavigableSet<E> extends SortedSet<E> { - /** - * Returns the greatest element in this set strictly less than the - * given element, or {@code null} if there is no such element. - * - * @param e the value to match - * @return the greatest element less than {@code e}, - * or {@code null} if there is no such element - * @throws ClassCastException if the specified element cannot be - * compared with the elements currently in the set - * @throws NullPointerException if the specified element is null - * and this set does not permit null elements - */ - E lower(E e); - - /** - * Returns the greatest element in this set less than or equal to - * the given element, or {@code null} if there is no such element. - * - * @param e the value to match - * @return the greatest element less than or equal to {@code e}, - * or {@code null} if there is no such element - * @throws ClassCastException if the specified element cannot be - * compared with the elements currently in the set - * @throws NullPointerException if the specified element is null - * and this set does not permit null elements - */ - E floor(E e); - - /** - * Returns the least element in this set greater than or equal to - * the given element, or {@code null} if there is no such element. - * - * @param e the value to match - * @return the least element greater than or equal to {@code e}, - * or {@code null} if there is no such element - * @throws ClassCastException if the specified element cannot be - * compared with the elements currently in the set - * @throws NullPointerException if the specified element is null - * and this set does not permit null elements - */ - E ceiling(E e); - - /** - * Returns the least element in this set strictly greater than the - * given element, or {@code null} if there is no such element. - * - * @param e the value to match - * @return the least element greater than {@code e}, - * or {@code null} if there is no such element - * @throws ClassCastException if the specified element cannot be - * compared with the elements currently in the set - * @throws NullPointerException if the specified element is null - * and this set does not permit null elements - */ - E higher(E e); - - /** - * Retrieves and removes the first (lowest) element, - * or returns {@code null} if this set is empty. - * - * @return the first element, or {@code null} if this set is empty - */ - E pollFirst(); - - /** - * Retrieves and removes the last (highest) element, - * or returns {@code null} if this set is empty. - * - * @return the last element, or {@code null} if this set is empty - */ - E pollLast(); - - /** - * Returns an iterator over the elements in this set, in ascending order. - * - * @return an iterator over the elements in this set, in ascending order - */ - Iterator<E> iterator(); - - /** - * Returns a reverse order view of the elements contained in this set. - * The descending set is backed by this set, so changes to the set are - * reflected in the descending set, and vice-versa. If either set is - * modified while an iteration over either set is in progress (except - * through the iterator's own {@code remove} operation), the results of - * the iteration are undefined. - * - * <p>The returned set has an ordering equivalent to - * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. - * The expression {@code s.descendingSet().descendingSet()} returns a - * view of {@code s} essentially equivalent to {@code s}. - * - * @return a reverse order view of this set - */ - NavigableSet<E> descendingSet(); - - /** - * Returns an iterator over the elements in this set, in descending order. - * Equivalent in effect to {@code descendingSet().iterator()}. - * - * @return an iterator over the elements in this set, in descending order - */ - Iterator<E> descendingIterator(); - - /** - * Returns a view of the portion of this set whose elements range from - * {@code fromElement} to {@code toElement}. If {@code fromElement} and - * {@code toElement} are equal, the returned set is empty unless {@code - * fromExclusive} and {@code toExclusive} are both true. The returned set - * is backed by this set, so changes in the returned set are reflected in - * this set, and vice-versa. The returned set supports all optional set - * operations that this set supports. - * - * <p>The returned set will throw an {@code IllegalArgumentException} - * on an attempt to insert an element outside its range. - * - * @param fromElement low endpoint of the returned set - * @param fromInclusive {@code true} if the low endpoint - * is to be included in the returned view - * @param toElement high endpoint of the returned set - * @param toInclusive {@code true} if the high endpoint - * is to be included in the returned view - * @return a view of the portion of this set whose elements range from - * {@code fromElement}, inclusive, to {@code toElement}, exclusive - * @throws ClassCastException if {@code fromElement} and - * {@code toElement} cannot be compared to one another using this - * set's comparator (or, if the set has no comparator, using - * natural ordering). Implementations may, but are not required - * to, throw this exception if {@code fromElement} or - * {@code toElement} cannot be compared to elements currently in - * the set. - * @throws NullPointerException if {@code fromElement} or - * {@code toElement} is null and this set does - * not permit null elements - * @throws IllegalArgumentException if {@code fromElement} is - * greater than {@code toElement}; or if this set itself - * has a restricted range, and {@code fromElement} or - * {@code toElement} lies outside the bounds of the range. - */ - NavigableSet<E> subSet(E fromElement, boolean fromInclusive, - E toElement, boolean toInclusive); - - /** - * Returns a view of the portion of this set whose elements are less than - * (or equal to, if {@code inclusive} is true) {@code toElement}. The - * returned set is backed by this set, so changes in the returned set are - * reflected in this set, and vice-versa. The returned set supports all - * optional set operations that this set supports. - * - * <p>The returned set will throw an {@code IllegalArgumentException} - * on an attempt to insert an element outside its range. - * - * @param toElement high endpoint of the returned set - * @param inclusive {@code true} if the high endpoint - * is to be included in the returned view - * @return a view of the portion of this set whose elements are less than - * (or equal to, if {@code inclusive} is true) {@code toElement} - * @throws ClassCastException if {@code toElement} is not compatible - * with this set's comparator (or, if the set has no comparator, - * if {@code toElement} does not implement {@link Comparable}). - * Implementations may, but are not required to, throw this - * exception if {@code toElement} cannot be compared to elements - * currently in the set. - * @throws NullPointerException if {@code toElement} is null and - * this set does not permit null elements - * @throws IllegalArgumentException if this set itself has a - * restricted range, and {@code toElement} lies outside the - * bounds of the range - */ - NavigableSet<E> headSet(E toElement, boolean inclusive); - - /** - * Returns a view of the portion of this set whose elements are greater - * than (or equal to, if {@code inclusive} is true) {@code fromElement}. - * The returned set is backed by this set, so changes in the returned set - * are reflected in this set, and vice-versa. The returned set supports - * all optional set operations that this set supports. - * - * <p>The returned set will throw an {@code IllegalArgumentException} - * on an attempt to insert an element outside its range. - * - * @param fromElement low endpoint of the returned set - * @param inclusive {@code true} if the low endpoint - * is to be included in the returned view - * @return a view of the portion of this set whose elements are greater - * than or equal to {@code fromElement} - * @throws ClassCastException if {@code fromElement} is not compatible - * with this set's comparator (or, if the set has no comparator, - * if {@code fromElement} does not implement {@link Comparable}). - * Implementations may, but are not required to, throw this - * exception if {@code fromElement} cannot be compared to elements - * currently in the set. - * @throws NullPointerException if {@code fromElement} is null - * and this set does not permit null elements - * @throws IllegalArgumentException if this set itself has a - * restricted range, and {@code fromElement} lies outside the - * bounds of the range - */ - NavigableSet<E> tailSet(E fromElement, boolean inclusive); - - /** - * {@inheritDoc} - * - * <p>Equivalent to {@code subSet(fromElement, true, toElement, false)}. - * - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - SortedSet<E> subSet(E fromElement, E toElement); - - /** - * {@inheritDoc} - * - * <p>Equivalent to {@code headSet(toElement, false)}. - * - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} -na */ - SortedSet<E> headSet(E toElement); - - /** - * {@inheritDoc} - * - * <p>Equivalent to {@code tailSet(fromElement, true)}. - * - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - SortedSet<E> tailSet(E fromElement); -} diff --git a/libjava/classpath/external/jsr166/java/util/Queue.java b/libjava/classpath/external/jsr166/java/util/Queue.java deleted file mode 100644 index 5711545..0000000 --- a/libjava/classpath/external/jsr166/java/util/Queue.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util; - -/** - * A collection designed for holding elements prior to processing. - * Besides basic {@link java.util.Collection Collection} operations, - * queues provide additional insertion, extraction, and inspection - * operations. Each of these methods exists in two forms: one throws - * an exception if the operation fails, the other returns a special - * value (either <tt>null</tt> or <tt>false</tt>, depending on the - * operation). The latter form of the insert operation is designed - * specifically for use with capacity-restricted <tt>Queue</tt> - * implementations; in most implementations, insert operations cannot - * fail. - * - * <p> - * <table BORDER CELLPADDING=3 CELLSPACING=1> - * <tr> - * <td></td> - * <td ALIGN=CENTER><em>Throws exception</em></td> - * <td ALIGN=CENTER><em>Returns special value</em></td> - * </tr> - * <tr> - * <td><b>Insert</b></td> - * <td>{@link #add add(e)}</td> - * <td>{@link #offer offer(e)}</td> - * </tr> - * <tr> - * <td><b>Remove</b></td> - * <td>{@link #remove remove()}</td> - * <td>{@link #poll poll()}</td> - * </tr> - * <tr> - * <td><b>Examine</b></td> - * <td>{@link #element element()}</td> - * <td>{@link #peek peek()}</td> - * </tr> - * </table> - * - * <p>Queues typically, but do not necessarily, order elements in a - * FIFO (first-in-first-out) manner. Among the exceptions are - * priority queues, which order elements according to a supplied - * comparator, or the elements' natural ordering, and LIFO queues (or - * stacks) which order the elements LIFO (last-in-first-out). - * Whatever the ordering used, the <em>head</em> of the queue is that - * element which would be removed by a call to {@link #remove() } or - * {@link #poll()}. In a FIFO queue, all new elements are inserted at - * the <em> tail</em> of the queue. Other kinds of queues may use - * different placement rules. Every <tt>Queue</tt> implementation - * must specify its ordering properties. - * - * <p>The {@link #offer offer} method inserts an element if possible, - * otherwise returning <tt>false</tt>. This differs from the {@link - * java.util.Collection#add Collection.add} method, which can fail to - * add an element only by throwing an unchecked exception. The - * <tt>offer</tt> method is designed for use when failure is a normal, - * rather than exceptional occurrence, for example, in fixed-capacity - * (or "bounded") queues. - * - * <p>The {@link #remove()} and {@link #poll()} methods remove and - * return the head of the queue. - * Exactly which element is removed from the queue is a - * function of the queue's ordering policy, which differs from - * implementation to implementation. The <tt>remove()</tt> and - * <tt>poll()</tt> methods differ only in their behavior when the - * queue is empty: the <tt>remove()</tt> method throws an exception, - * while the <tt>poll()</tt> method returns <tt>null</tt>. - * - * <p>The {@link #element()} and {@link #peek()} methods return, but do - * not remove, the head of the queue. - * - * <p>The <tt>Queue</tt> interface does not define the <i>blocking queue - * methods</i>, which are common in concurrent programming. These methods, - * which wait for elements to appear or for space to become available, are - * defined in the {@link java.util.concurrent.BlockingQueue} interface, which - * extends this interface. - * - * <p><tt>Queue</tt> implementations generally do not allow insertion - * of <tt>null</tt> elements, although some implementations, such as - * {@link LinkedList}, do not prohibit insertion of <tt>null</tt>. - * Even in the implementations that permit it, <tt>null</tt> should - * not be inserted into a <tt>Queue</tt>, as <tt>null</tt> is also - * used as a special return value by the <tt>poll</tt> method to - * indicate that the queue contains no elements. - * - * <p><tt>Queue</tt> implementations generally do not define - * element-based versions of methods <tt>equals</tt> and - * <tt>hashCode</tt> but instead inherit the identity based versions - * from class <tt>Object</tt>, because element-based equality is not - * always well-defined for queues with the same elements but different - * ordering properties. - * - * - * <p>This interface is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @see java.util.Collection - * @see LinkedList - * @see PriorityQueue - * @see java.util.concurrent.LinkedBlockingQueue - * @see java.util.concurrent.BlockingQueue - * @see java.util.concurrent.ArrayBlockingQueue - * @see java.util.concurrent.LinkedBlockingQueue - * @see java.util.concurrent.PriorityBlockingQueue - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ -public interface Queue<E> extends Collection<E> { - /** - * Inserts the specified element into this queue if it is possible to do so - * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt> - * if no space is currently available. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws IllegalStateException if the element cannot be added at this - * time due to capacity restrictions - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this queue - * @throws NullPointerException if the specified element is null and - * this queue does not permit null elements - * @throws IllegalArgumentException if some property of this element - * prevents it from being added to this queue - */ - boolean add(E e); - - /** - * Inserts the specified element into this queue if it is possible to do - * so immediately without violating capacity restrictions. - * When using a capacity-restricted queue, this method is generally - * preferable to {@link #add}, which can fail to insert an element only - * by throwing an exception. - * - * @param e the element to add - * @return <tt>true</tt> if the element was added to this queue, else - * <tt>false</tt> - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this queue - * @throws NullPointerException if the specified element is null and - * this queue does not permit null elements - * @throws IllegalArgumentException if some property of this element - * prevents it from being added to this queue - */ - boolean offer(E e); - - /** - * Retrieves and removes the head of this queue. This method differs - * from {@link #poll poll} only in that it throws an exception if this - * queue is empty. - * - * @return the head of this queue - * @throws NoSuchElementException if this queue is empty - */ - E remove(); - - /** - * Retrieves and removes the head of this queue, - * or returns <tt>null</tt> if this queue is empty. - * - * @return the head of this queue, or <tt>null</tt> if this queue is empty - */ - E poll(); - - /** - * Retrieves, but does not remove, the head of this queue. This method - * differs from {@link #peek peek} only in that it throws an exception - * if this queue is empty. - * - * @return the head of this queue - * @throws NoSuchElementException if this queue is empty - */ - E element(); - - /** - * Retrieves, but does not remove, the head of this queue, - * or returns <tt>null</tt> if this queue is empty. - * - * @return the head of this queue, or <tt>null</tt> if this queue is empty - */ - E peek(); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java b/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java deleted file mode 100644 index ac15c50..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; - -/** - * Provides default implementations of {@link ExecutorService} - * execution methods. This class implements the <tt>submit</tt>, - * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a - * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults - * to the {@link FutureTask} class provided in this package. For example, - * the implementation of <tt>submit(Runnable)</tt> creates an - * associated <tt>RunnableFuture</tt> that is executed and - * returned. Subclasses may override the <tt>newTaskFor</tt> methods - * to return <tt>RunnableFuture</tt> implementations other than - * <tt>FutureTask</tt>. - * - * <p> <b>Extension example</b>. Here is a sketch of a class - * that customizes {@link ThreadPoolExecutor} to use - * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>: - * <pre> - * public class CustomThreadPoolExecutor extends ThreadPoolExecutor { - * - * static class CustomTask<V> implements RunnableFuture<V> {...} - * - * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) { - * return new CustomTask<V>(c); - * } - * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) { - * return new CustomTask<V>(r, v); - * } - * // ... add constructors, etc. - * } - * </pre> - * @since 1.5 - * @author Doug Lea - */ -public abstract class AbstractExecutorService implements ExecutorService { - - /** - * Returns a <tt>RunnableFuture</tt> for the given runnable and default - * value. - * - * @param runnable the runnable task being wrapped - * @param value the default value for the returned future - * @return a <tt>RunnableFuture</tt> which when run will run the - * underlying runnable and which, as a <tt>Future</tt>, will yield - * the given value as its result and provide for cancellation of - * the underlying task. - * @since 1.6 - */ - protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { - return new FutureTask<T>(runnable, value); - } - - /** - * Returns a <tt>RunnableFuture</tt> for the given callable task. - * - * @param callable the callable task being wrapped - * @return a <tt>RunnableFuture</tt> which when run will call the - * underlying callable and which, as a <tt>Future</tt>, will yield - * the callable's result as its result and provide for - * cancellation of the underlying task. - * @since 1.6 - */ - protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { - return new FutureTask<T>(callable); - } - - public Future<?> submit(Runnable task) { - if (task == null) throw new NullPointerException(); - RunnableFuture<Object> ftask = newTaskFor(task, null); - execute(ftask); - return ftask; - } - - public <T> Future<T> submit(Runnable task, T result) { - if (task == null) throw new NullPointerException(); - RunnableFuture<T> ftask = newTaskFor(task, result); - execute(ftask); - return ftask; - } - - public <T> Future<T> submit(Callable<T> task) { - if (task == null) throw new NullPointerException(); - RunnableFuture<T> ftask = newTaskFor(task); - execute(ftask); - return ftask; - } - - /** - * the main mechanics of invokeAny. - */ - private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks, - boolean timed, long nanos) - throws InterruptedException, ExecutionException, TimeoutException { - if (tasks == null) - throw new NullPointerException(); - int ntasks = tasks.size(); - if (ntasks == 0) - throw new IllegalArgumentException(); - List<Future<T>> futures= new ArrayList<Future<T>>(ntasks); - ExecutorCompletionService<T> ecs = - new ExecutorCompletionService<T>(this); - - // For efficiency, especially in executors with limited - // parallelism, check to see if previously submitted tasks are - // done before submitting more of them. This interleaving - // plus the exception mechanics account for messiness of main - // loop. - - try { - // Record exceptions so that if we fail to obtain any - // result, we can throw the last exception we got. - ExecutionException ee = null; - long lastTime = (timed)? System.nanoTime() : 0; - Iterator<? extends Callable<T>> it = tasks.iterator(); - - // Start one task for sure; the rest incrementally - futures.add(ecs.submit(it.next())); - --ntasks; - int active = 1; - - for (;;) { - Future<T> f = ecs.poll(); - if (f == null) { - if (ntasks > 0) { - --ntasks; - futures.add(ecs.submit(it.next())); - ++active; - } - else if (active == 0) - break; - else if (timed) { - f = ecs.poll(nanos, TimeUnit.NANOSECONDS); - if (f == null) - throw new TimeoutException(); - long now = System.nanoTime(); - nanos -= now - lastTime; - lastTime = now; - } - else - f = ecs.take(); - } - if (f != null) { - --active; - try { - return f.get(); - } catch (InterruptedException ie) { - throw ie; - } catch (ExecutionException eex) { - ee = eex; - } catch (RuntimeException rex) { - ee = new ExecutionException(rex); - } - } - } - - if (ee == null) - ee = new ExecutionException(); - throw ee; - - } finally { - for (Future<T> f : futures) - f.cancel(true); - } - } - - public <T> T invokeAny(Collection<? extends Callable<T>> tasks) - throws InterruptedException, ExecutionException { - try { - return doInvokeAny(tasks, false, 0); - } catch (TimeoutException cannotHappen) { - assert false; - return null; - } - } - - public <T> T invokeAny(Collection<? extends Callable<T>> tasks, - long timeout, TimeUnit unit) - throws InterruptedException, ExecutionException, TimeoutException { - return doInvokeAny(tasks, true, unit.toNanos(timeout)); - } - - public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) - throws InterruptedException { - if (tasks == null) - throw new NullPointerException(); - List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); - boolean done = false; - try { - for (Callable<T> t : tasks) { - RunnableFuture<T> f = newTaskFor(t); - futures.add(f); - execute(f); - } - for (Future<T> f : futures) { - if (!f.isDone()) { - try { - f.get(); - } catch (CancellationException ignore) { - } catch (ExecutionException ignore) { - } - } - } - done = true; - return futures; - } finally { - if (!done) - for (Future<T> f : futures) - f.cancel(true); - } - } - - public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, - long timeout, TimeUnit unit) - throws InterruptedException { - if (tasks == null || unit == null) - throw new NullPointerException(); - long nanos = unit.toNanos(timeout); - List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); - boolean done = false; - try { - for (Callable<T> t : tasks) - futures.add(newTaskFor(t)); - - long lastTime = System.nanoTime(); - - // Interleave time checks and calls to execute in case - // executor doesn't have any/much parallelism. - Iterator<Future<T>> it = futures.iterator(); - while (it.hasNext()) { - execute((Runnable)(it.next())); - long now = System.nanoTime(); - nanos -= now - lastTime; - lastTime = now; - if (nanos <= 0) - return futures; - } - - for (Future<T> f : futures) { - if (!f.isDone()) { - if (nanos <= 0) - return futures; - try { - f.get(nanos, TimeUnit.NANOSECONDS); - } catch (CancellationException ignore) { - } catch (ExecutionException ignore) { - } catch (TimeoutException toe) { - return futures; - } - long now = System.nanoTime(); - nanos -= now - lastTime; - lastTime = now; - } - } - done = true; - return futures; - } finally { - if (!done) - for (Future<T> f : futures) - f.cancel(true); - } - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ArrayBlockingQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/ArrayBlockingQueue.java deleted file mode 100644 index 3ce9ed8..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ArrayBlockingQueue.java +++ /dev/null @@ -1,778 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.locks.*; -import java.util.*; - -/** - * A bounded {@linkplain BlockingQueue blocking queue} backed by an - * array. This queue orders elements FIFO (first-in-first-out). The - * <em>head</em> of the queue is that element that has been on the - * queue the longest time. The <em>tail</em> of the queue is that - * element that has been on the queue the shortest time. New elements - * are inserted at the tail of the queue, and the queue retrieval - * operations obtain elements at the head of the queue. - * - * <p>This is a classic "bounded buffer", in which a - * fixed-sized array holds elements inserted by producers and - * extracted by consumers. Once created, the capacity cannot be - * increased. Attempts to <tt>put</tt> an element into a full queue - * will result in the operation blocking; attempts to <tt>take</tt> an - * element from an empty queue will similarly block. - * - * <p> This class supports an optional fairness policy for ordering - * waiting producer and consumer threads. By default, this ordering - * is not guaranteed. However, a queue constructed with fairness set - * to <tt>true</tt> grants threads access in FIFO order. Fairness - * generally decreases throughput but reduces variability and avoids - * starvation. - * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ -public class ArrayBlockingQueue<E> extends AbstractQueue<E> - implements BlockingQueue<E>, java.io.Serializable { - - /** - * Serialization 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 static final long serialVersionUID = -817911632652898426L; - - /** The queued items */ - private final E[] items; - /** items index for next take, poll or remove */ - private int takeIndex; - /** items index for next put, offer, or add. */ - private int putIndex; - /** Number of items in the queue */ - private int count; - - /* - * Concurrency control uses the classic two-condition algorithm - * found in any textbook. - */ - - /** Main lock guarding all access */ - private final ReentrantLock lock; - /** Condition for waiting takes */ - private final Condition notEmpty; - /** Condition for waiting puts */ - private final Condition notFull; - - // Internal helper methods - - /** - * Circularly increment i. - */ - final int inc(int i) { - return (++i == items.length)? 0 : i; - } - - /** - * Inserts element at current put position, advances, and signals. - * Call only when holding lock. - */ - private void insert(E x) { - items[putIndex] = x; - putIndex = inc(putIndex); - ++count; - notEmpty.signal(); - } - - /** - * Extracts element at current take position, advances, and signals. - * Call only when holding lock. - */ - private E extract() { - final E[] items = this.items; - E x = items[takeIndex]; - items[takeIndex] = null; - takeIndex = inc(takeIndex); - --count; - notFull.signal(); - return x; - } - - /** - * Utility for remove and iterator.remove: Delete item at position i. - * Call only when holding lock. - */ - void removeAt(int i) { - 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(); - } - - /** - * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed) - * capacity and default access policy. - * - * @param capacity the capacity of this queue - * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1 - */ - public ArrayBlockingQueue(int capacity) { - this(capacity, false); - } - - /** - * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed) - * capacity and the specified access policy. - * - * @param capacity the capacity of this queue - * @param fair if <tt>true</tt> then queue accesses for threads blocked - * on insertion or removal, are processed in FIFO order; - * if <tt>false</tt> the access order is unspecified. - * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1 - */ - public ArrayBlockingQueue(int capacity, boolean fair) { - if (capacity <= 0) - throw new IllegalArgumentException(); - this.items = (E[]) new Object[capacity]; - lock = new ReentrantLock(fair); - notEmpty = lock.newCondition(); - notFull = lock.newCondition(); - } - - /** - * Creates an <tt>ArrayBlockingQueue</tt> 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. - * - * @param capacity the capacity of this queue - * @param fair if <tt>true</tt> then queue accesses for threads blocked - * on insertion or removal, are processed in FIFO order; - * if <tt>false</tt> the access order is unspecified. - * @param c the collection of elements to initially contain - * @throws IllegalArgumentException if <tt>capacity</tt> is less than - * <tt>c.size()</tt>, or less than 1. - * @throws NullPointerException if the specified collection or any - * of its elements are null - */ - public ArrayBlockingQueue(int capacity, boolean fair, - Collection<? extends E> c) { - this(capacity, fair); - if (capacity < c.size()) - throw new IllegalArgumentException(); - - for (Iterator<? extends E> it = c.iterator(); it.hasNext();) - add(it.next()); - } - - /** - * Inserts the specified element at the tail of this queue if it is - * possible to do so immediately without exceeding the queue's capacity, - * returning <tt>true</tt> upon success and throwing an - * <tt>IllegalStateException</tt> if this queue is full. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws IllegalStateException if this queue is full - * @throws NullPointerException if the specified element is null - */ - public boolean add(E e) { - return super.add(e); - } - - /** - * Inserts the specified element at the tail of this queue if it is - * possible to do so immediately without exceeding the queue's capacity, - * returning <tt>true</tt> upon success and <tt>false</tt> if this queue - * is full. This method is generally preferable to method {@link #add}, - * which can fail to insert an element only by throwing an exception. - * - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e) { - if (e == null) throw new NullPointerException(); - final ReentrantLock lock = this.lock; - lock.lock(); - try { - if (count == items.length) - return false; - else { - insert(e); - return true; - } - } finally { - lock.unlock(); - } - } - - /** - * Inserts the specified element at the tail of this queue, waiting - * for space to become available if the queue is full. - * - * @throws InterruptedException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public void put(E e) throws InterruptedException { - if (e == 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(e); - } finally { - lock.unlock(); - } - } - - /** - * Inserts the specified element at the tail of this queue, waiting - * up to the specified wait time for space to become available if - * the queue is full. - * - * @throws InterruptedException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public boolean offer(E e, long timeout, TimeUnit unit) - throws InterruptedException { - - if (e == null) throw new NullPointerException(); - long nanos = unit.toNanos(timeout); - final ReentrantLock lock = this.lock; - lock.lockInterruptibly(); - try { - for (;;) { - if (count != items.length) { - insert(e); - 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 poll() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - if (count == 0) - return null; - E x = extract(); - return x; - } finally { - lock.unlock(); - } - } - - public E take() throws InterruptedException { - 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 E poll(long timeout, TimeUnit unit) throws InterruptedException { - long nanos = unit.toNanos(timeout); - final ReentrantLock lock = this.lock; - lock.lockInterruptibly(); - try { - 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 E peek() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return (count == 0) ? null : items[takeIndex]; - } finally { - lock.unlock(); - } - } - - // this doc comment is overridden to remove the reference to collections - // greater in size than Integer.MAX_VALUE - /** - * Returns the number of elements in this queue. - * - * @return the number of elements in this queue - */ - public int size() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return count; - } finally { - lock.unlock(); - } - } - - // this doc comment is a modified copy of the inherited doc comment, - // without the reference to unlimited queues. - /** - * Returns the number of additional 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 <tt>size</tt> of this queue. - * - * <p>Note that you <em>cannot</em> always tell if an attempt to insert - * an element will succeed by inspecting <tt>remainingCapacity</tt> - * because it may be the case that another thread is about to - * insert or remove an element. - */ - public int remainingCapacity() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return items.length - count; - } finally { - lock.unlock(); - } - } - - /** - * Removes a single instance of the specified element from this queue, - * if it is present. More formally, removes an element <tt>e</tt> such - * that <tt>o.equals(e)</tt>, if this queue contains one or more such - * elements. - * Returns <tt>true</tt> if this queue contained the specified element - * (or equivalently, if this queue changed as a result of the call). - * - * @param o element to be removed from this queue, if present - * @return <tt>true</tt> if this queue changed as a result of the call - */ - public boolean remove(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(); - } - } - - /** - * Returns <tt>true</tt> if this queue contains the specified element. - * More formally, returns <tt>true</tt> if and only if this queue contains - * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. - * - * @param o object to be checked for containment in this queue - * @return <tt>true</tt> if this queue contains the specified element - */ - public boolean contains(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(); - } - } - - /** - * Returns an array containing all of the elements in this queue, in - * proper sequence. - * - * <p>The returned array will be "safe" in that no references to it are - * maintained by this queue. (In other words, this method must allocate - * a new array). The caller is thus free to modify the returned array. - * - * <p>This method acts as bridge between array-based and collection-based - * APIs. - * - * @return an array containing all of the elements in this queue - */ - public 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(); - } - } - - /** - * Returns an array containing all of the elements in this queue, in - * proper sequence; the runtime type of the returned array is that of - * the specified array. If the queue fits in the specified array, it - * is returned therein. Otherwise, a new array is allocated with the - * runtime type of the specified array and the size of this queue. - * - * <p>If this queue fits in the specified array with room to spare - * (i.e., the array has more elements than this queue), the element in - * the array immediately following the end of the queue is set to - * <tt>null</tt>. - * - * <p>Like the {@link #toArray()} method, this method acts as bridge between - * array-based and collection-based APIs. Further, this method allows - * precise control over the runtime type of the output array, and may, - * under certain circumstances, be used to save allocation costs. - * - * <p>Suppose <tt>x</tt> is a queue known to contain only strings. - * The following code can be used to dump the queue into a newly - * allocated array of <tt>String</tt>: - * - * <pre> - * String[] y = x.toArray(new String[0]);</pre> - * - * Note that <tt>toArray(new Object[0])</tt> is identical in function to - * <tt>toArray()</tt>. - * - * @param a the array into which the elements of the queue are to - * be stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose - * @return an array containing all of the elements in this queue - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in - * this queue - * @throws NullPointerException if the specified array is null - */ - public <T> 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 String toString() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return super.toString(); - } finally { - lock.unlock(); - } - } - - /** - * Atomically removes all of the elements from this queue. - * The queue will be empty after this call returns. - */ - 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(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> 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(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> 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(); - } - } - - - /** - * Returns an iterator over the elements in this queue in proper sequence. - * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that - * will never throw {@link 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. - * - * @return an iterator over the elements in this queue in proper sequence - */ - public Iterator<E> iterator() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return new Itr(); - } finally { - lock.unlock(); - } - } - - /** - * Iterator for ArrayBlockingQueue - */ - private class Itr implements Iterator<E> { - /** - * Index of element to be returned by next, - * or a negative number if no such. - */ - private int nextIndex; - - /** - * nextItem holds on to item fields because once we claim - * that an element exists in hasNext(), we must return it in - * the following next() call even if it was in the process of - * being removed when hasNext() was called. - */ - private E nextItem; - - /** - * Index of element returned by most recent call to next. - * Reset to -1 if this element is deleted by a call to remove. - */ - private int lastRet; - - Itr() { - lastRet = -1; - if (count == 0) - nextIndex = -1; - else { - nextIndex = takeIndex; - nextItem = items[takeIndex]; - } - } - - public boolean hasNext() { - /* - * No sync. We can return true by mistake here - * only if this iterator passed across threads, - * which we don't support anyway. - */ - return nextIndex >= 0; - } - - /** - * Checks whether nextIndex is valid; if so setting nextItem. - * Stops iterator when either hits putIndex or sees null item. - */ - private void checkNext() { - if (nextIndex == putIndex) { - nextIndex = -1; - nextItem = null; - } else { - nextItem = items[nextIndex]; - if (nextItem == null) - nextIndex = -1; - } - } - - public E next() { - final ReentrantLock lock = ArrayBlockingQueue.this.lock; - lock.lock(); - try { - if (nextIndex < 0) - throw new NoSuchElementException(); - lastRet = nextIndex; - E x = nextItem; - nextIndex = inc(nextIndex); - checkNext(); - return x; - } finally { - lock.unlock(); - } - } - - public void remove() { - final ReentrantLock lock = ArrayBlockingQueue.this.lock; - lock.lock(); - try { - int i = lastRet; - if (i == -1) - throw new IllegalStateException(); - lastRet = -1; - - int ti = takeIndex; - removeAt(i); - // back up cursor (reset to front if was first element) - nextIndex = (i == ti) ? takeIndex : i; - checkNext(); - } finally { - lock.unlock(); - } - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/BlockingDeque.java b/libjava/classpath/external/jsr166/java/util/concurrent/BlockingDeque.java deleted file mode 100644 index d77a965..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/BlockingDeque.java +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; - -/** - * A {@link Deque} that additionally supports blocking operations that wait - * for the deque to become non-empty when retrieving an element, and wait for - * space to become available in the deque when storing an element. - * - * <p><tt>BlockingDeque</tt> methods come in four forms, with different ways - * of handling operations that cannot be satisfied immediately, but may be - * satisfied at some point in the future: - * one throws an exception, the second returns a special value (either - * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third - * blocks the current thread indefinitely until the operation can succeed, - * and the fourth blocks for only a given maximum time limit before giving - * up. These methods are summarized in the following table: - * - * <p> - * <table BORDER CELLPADDING=3 CELLSPACING=1> - * <tr> - * <td ALIGN=CENTER COLSPAN = 5> <b>First Element (Head)</b></td> - * </tr> - * <tr> - * <td></td> - * <td ALIGN=CENTER><em>Throws exception</em></td> - * <td ALIGN=CENTER><em>Special value</em></td> - * <td ALIGN=CENTER><em>Blocks</em></td> - * <td ALIGN=CENTER><em>Times out</em></td> - * </tr> - * <tr> - * <td><b>Insert</b></td> - * <td>{@link #addFirst addFirst(e)}</td> - * <td>{@link #offerFirst(Object) offerFirst(e)}</td> - * <td>{@link #putFirst putFirst(e)}</td> - * <td>{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td> - * </tr> - * <tr> - * <td><b>Remove</b></td> - * <td>{@link #removeFirst removeFirst()}</td> - * <td>{@link #pollFirst pollFirst()}</td> - * <td>{@link #takeFirst takeFirst()}</td> - * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td> - * </tr> - * <tr> - * <td><b>Examine</b></td> - * <td>{@link #getFirst getFirst()}</td> - * <td>{@link #peekFirst peekFirst()}</td> - * <td><em>not applicable</em></td> - * <td><em>not applicable</em></td> - * </tr> - * <tr> - * <td ALIGN=CENTER COLSPAN = 5> <b>Last Element (Tail)</b></td> - * </tr> - * <tr> - * <td></td> - * <td ALIGN=CENTER><em>Throws exception</em></td> - * <td ALIGN=CENTER><em>Special value</em></td> - * <td ALIGN=CENTER><em>Blocks</em></td> - * <td ALIGN=CENTER><em>Times out</em></td> - * </tr> - * <tr> - * <td><b>Insert</b></td> - * <td>{@link #addLast addLast(e)}</td> - * <td>{@link #offerLast(Object) offerLast(e)}</td> - * <td>{@link #putLast putLast(e)}</td> - * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td> - * </tr> - * <tr> - * <td><b>Remove</b></td> - * <td>{@link #removeLast() removeLast()}</td> - * <td>{@link #pollLast() pollLast()}</td> - * <td>{@link #takeLast takeLast()}</td> - * <td>{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td> - * </tr> - * <tr> - * <td><b>Examine</b></td> - * <td>{@link #getLast getLast()}</td> - * <td>{@link #peekLast peekLast()}</td> - * <td><em>not applicable</em></td> - * <td><em>not applicable</em></td> - * </tr> - * </table> - * - * <p>Like any {@link BlockingQueue}, a <tt>BlockingDeque</tt> is thread safe, - * does not permit null elements, and may (or may not) be - * capacity-constrained. - * - * <p>A <tt>BlockingDeque</tt> implementation may be used directly as a FIFO - * <tt>BlockingQueue</tt>. The methods inherited from the - * <tt>BlockingQueue</tt> interface are precisely equivalent to - * <tt>BlockingDeque</tt> methods as indicated in the following table: - * - * <p> - * <table BORDER CELLPADDING=3 CELLSPACING=1> - * <tr> - * <td ALIGN=CENTER> <b><tt>BlockingQueue</tt> Method</b></td> - * <td ALIGN=CENTER> <b>Equivalent <tt>BlockingDeque</tt> Method</b></td> - * </tr> - * <tr> - * <td ALIGN=CENTER COLSPAN = 2> <b>Insert</b></td> - * </tr> - * <tr> - * <td>{@link #add(Object) add(e)}</td> - * <td>{@link #addLast(Object) addLast(e)}</td> - * </tr> - * <tr> - * <td>{@link #offer(Object) offer(e)}</td> - * <td>{@link #offerLast(Object) offerLast(e)}</td> - * </tr> - * <tr> - * <td>{@link #put(Object) put(e)}</td> - * <td>{@link #putLast(Object) putLast(e)}</td> - * </tr> - * <tr> - * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td> - * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td> - * </tr> - * <tr> - * <td ALIGN=CENTER COLSPAN = 2> <b>Remove</b></td> - * </tr> - * <tr> - * <td>{@link #remove() remove()}</td> - * <td>{@link #removeFirst() removeFirst()}</td> - * </tr> - * <tr> - * <td>{@link #poll() poll()}</td> - * <td>{@link #pollFirst() pollFirst()}</td> - * </tr> - * <tr> - * <td>{@link #take() take()}</td> - * <td>{@link #takeFirst() takeFirst()}</td> - * </tr> - * <tr> - * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td> - * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td> - * </tr> - * <tr> - * <td ALIGN=CENTER COLSPAN = 2> <b>Examine</b></td> - * </tr> - * <tr> - * <td>{@link #element() element()}</td> - * <td>{@link #getFirst() getFirst()}</td> - * </tr> - * <tr> - * <td>{@link #peek() peek()}</td> - * <td>{@link #peekFirst() peekFirst()}</td> - * </tr> - * </table> - * - * <p>Memory consistency effects: As with other concurrent - * collections, actions in a thread prior to placing an object into a - * {@code BlockingDeque} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * actions subsequent to the access or removal of that element from - * the {@code BlockingDeque} in another thread. - * - * <p>This interface is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.6 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ -public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> { - /* - * We have "diamond" multiple interface inheritance here, and that - * introduces ambiguities. Methods might end up with different - * specs depending on the branch chosen by javadoc. Thus a lot of - * methods specs here are copied from superinterfaces. - */ - - /** - * Inserts the specified element at the front of this deque if it is - * possible to do so immediately without violating capacity restrictions, - * throwing an <tt>IllegalStateException</tt> if no space is currently - * available. When using a capacity-restricted deque, it is generally - * preferable to use {@link #offerFirst(Object) offerFirst}. - * - * @param e the element to add - * @throws IllegalStateException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException {@inheritDoc} - */ - void addFirst(E e); - - /** - * Inserts the specified element at the end of this deque if it is - * possible to do so immediately without violating capacity restrictions, - * throwing an <tt>IllegalStateException</tt> if no space is currently - * available. When using a capacity-restricted deque, it is generally - * preferable to use {@link #offerLast(Object) offerLast}. - * - * @param e the element to add - * @throws IllegalStateException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException {@inheritDoc} - */ - void addLast(E e); - - /** - * Inserts the specified element at the front of this deque if it is - * possible to do so immediately without violating capacity restrictions, - * returning <tt>true</tt> upon success and <tt>false</tt> if no space is - * currently available. - * When using a capacity-restricted deque, this method is generally - * preferable to the {@link #addFirst(Object) addFirst} method, which can - * fail to insert an element only by throwing an exception. - * - * @param e the element to add - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException {@inheritDoc} - */ - boolean offerFirst(E e); - - /** - * Inserts the specified element at the end of this deque if it is - * possible to do so immediately without violating capacity restrictions, - * returning <tt>true</tt> upon success and <tt>false</tt> if no space is - * currently available. - * When using a capacity-restricted deque, this method is generally - * preferable to the {@link #addLast(Object) addLast} method, which can - * fail to insert an element only by throwing an exception. - * - * @param e the element to add - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException {@inheritDoc} - */ - boolean offerLast(E e); - - /** - * Inserts the specified element at the front of this deque, - * waiting if necessary for space to become available. - * - * @param e the element to add - * @throws InterruptedException if interrupted while waiting - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - void putFirst(E e) throws InterruptedException; - - /** - * Inserts the specified element at the end of this deque, - * waiting if necessary for space to become available. - * - * @param e the element to add - * @throws InterruptedException if interrupted while waiting - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - void putLast(E e) throws InterruptedException; - - /** - * Inserts the specified element at the front of this deque, - * waiting up to the specified wait time if necessary for space to - * become available. - * - * @param e the element to add - * @param timeout how long to wait before giving up, in units of - * <tt>unit</tt> - * @param unit a <tt>TimeUnit</tt> determining how to interpret the - * <tt>timeout</tt> parameter - * @return <tt>true</tt> if successful, or <tt>false</tt> if - * the specified waiting time elapses before space is available - * @throws InterruptedException if interrupted while waiting - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean offerFirst(E e, long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Inserts the specified element at the end of this deque, - * waiting up to the specified wait time if necessary for space to - * become available. - * - * @param e the element to add - * @param timeout how long to wait before giving up, in units of - * <tt>unit</tt> - * @param unit a <tt>TimeUnit</tt> determining how to interpret the - * <tt>timeout</tt> parameter - * @return <tt>true</tt> if successful, or <tt>false</tt> if - * the specified waiting time elapses before space is available - * @throws InterruptedException if interrupted while waiting - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean offerLast(E e, long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Retrieves and removes the first element of this deque, waiting - * if necessary until an element becomes available. - * - * @return the head of this deque - * @throws InterruptedException if interrupted while waiting - */ - E takeFirst() throws InterruptedException; - - /** - * Retrieves and removes the last element of this deque, waiting - * if necessary until an element becomes available. - * - * @return the tail of this deque - * @throws InterruptedException if interrupted while waiting - */ - E takeLast() throws InterruptedException; - - /** - * Retrieves and removes the first element of this deque, waiting - * up to the specified wait time if necessary for an element to - * become available. - * - * @param timeout how long to wait before giving up, in units of - * <tt>unit</tt> - * @param unit a <tt>TimeUnit</tt> determining how to interpret the - * <tt>timeout</tt> parameter - * @return the head of this deque, or <tt>null</tt> if the specified - * waiting time elapses before an element is available - * @throws InterruptedException if interrupted while waiting - */ - E pollFirst(long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Retrieves and removes the last element of this deque, waiting - * up to the specified wait time if necessary for an element to - * become available. - * - * @param timeout how long to wait before giving up, in units of - * <tt>unit</tt> - * @param unit a <tt>TimeUnit</tt> determining how to interpret the - * <tt>timeout</tt> parameter - * @return the tail of this deque, or <tt>null</tt> if the specified - * waiting time elapses before an element is available - * @throws InterruptedException if interrupted while waiting - */ - E pollLast(long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Removes the first occurrence of the specified element from this deque. - * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that - * <tt>o.equals(e)</tt> (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if an element was removed as a result of this call - * @throws ClassCastException if the class of the specified element - * is incompatible with this deque (optional) - * @throws NullPointerException if the specified element is null (optional) - */ - boolean removeFirstOccurrence(Object o); - - /** - * Removes the last occurrence of the specified element from this deque. - * If the deque does not contain the element, it is unchanged. - * More formally, removes the last element <tt>e</tt> such that - * <tt>o.equals(e)</tt> (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if an element was removed as a result of this call - * @throws ClassCastException if the class of the specified element - * is incompatible with this deque (optional) - * @throws NullPointerException if the specified element is null (optional) - */ - boolean removeLastOccurrence(Object o); - - // *** BlockingQueue methods *** - - /** - * Inserts the specified element into the queue represented by this deque - * (in other words, at the tail of this deque) if it is possible to do so - * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an - * <tt>IllegalStateException</tt> if no space is currently available. - * When using a capacity-restricted deque, it is generally preferable to - * use {@link #offer(Object) offer}. - * - * <p>This method is equivalent to {@link #addLast(Object) addLast}. - * - * @param e the element to add - * @throws IllegalStateException {@inheritDoc} - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean add(E e); - - /** - * Inserts the specified element into the queue represented by this deque - * (in other words, at the tail of this deque) if it is possible to do so - * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and <tt>false</tt> if no space is currently - * available. When using a capacity-restricted deque, this method is - * generally preferable to the {@link #add} method, which can fail to - * insert an element only by throwing an exception. - * - * <p>This method is equivalent to {@link #offerLast(Object) offerLast}. - * - * @param e the element to add - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean offer(E e); - - /** - * Inserts the specified element into the queue represented by this deque - * (in other words, at the tail of this deque), waiting if necessary for - * space to become available. - * - * <p>This method is equivalent to {@link #putLast(Object) putLast}. - * - * @param e the element to add - * @throws InterruptedException {@inheritDoc} - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - void put(E e) throws InterruptedException; - - /** - * Inserts the specified element into the queue represented by this deque - * (in other words, at the tail of this deque), waiting up to the - * specified wait time if necessary for space to become available. - * - * <p>This method is equivalent to - * {@link #offerLast(Object,long,TimeUnit) offerLast}. - * - * @param e the element to add - * @return <tt>true</tt> if the element was added to this deque, else - * <tt>false</tt> - * @throws InterruptedException {@inheritDoc} - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this deque - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this deque - */ - boolean offer(E e, long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Retrieves and removes the head of the queue represented by this deque - * (in other words, the first element of this deque). - * This method differs from {@link #poll poll} only in that it - * throws an exception if this deque is empty. - * - * <p>This method is equivalent to {@link #removeFirst() removeFirst}. - * - * @return the head of the queue represented by this deque - * @throws NoSuchElementException if this deque is empty - */ - E remove(); - - /** - * Retrieves and removes the head of the queue represented by this deque - * (in other words, the first element of this deque), or returns - * <tt>null</tt> if this deque is empty. - * - * <p>This method is equivalent to {@link #pollFirst()}. - * - * @return the head of this deque, or <tt>null</tt> if this deque is empty - */ - E poll(); - - /** - * Retrieves and removes the head of the queue represented by this deque - * (in other words, the first element of this deque), waiting if - * necessary until an element becomes available. - * - * <p>This method is equivalent to {@link #takeFirst() takeFirst}. - * - * @return the head of this deque - * @throws InterruptedException if interrupted while waiting - */ - E take() throws InterruptedException; - - /** - * Retrieves and removes the head of the queue represented by this deque - * (in other words, the first element of this deque), waiting up to the - * specified wait time if necessary for an element to become available. - * - * <p>This method is equivalent to - * {@link #pollFirst(long,TimeUnit) pollFirst}. - * - * @return the head of this deque, or <tt>null</tt> if the - * specified waiting time elapses before an element is available - * @throws InterruptedException if interrupted while waiting - */ - E poll(long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Retrieves, but does not remove, the head of the queue represented by - * this deque (in other words, the first element of this deque). - * This method differs from {@link #peek peek} only in that it throws an - * exception if this deque is empty. - * - * <p>This method is equivalent to {@link #getFirst() getFirst}. - * - * @return the head of this deque - * @throws NoSuchElementException if this deque is empty - */ - E element(); - - /** - * Retrieves, but does not remove, the head of the queue represented by - * this deque (in other words, the first element of this deque), or - * returns <tt>null</tt> if this deque is empty. - * - * <p>This method is equivalent to {@link #peekFirst() peekFirst}. - * - * @return the head of this deque, or <tt>null</tt> if this deque is empty - */ - E peek(); - - /** - * Removes the first occurrence of the specified element from this deque. - * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that - * <tt>o.equals(e)</tt> (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * <p>This method is equivalent to - * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}. - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if this deque changed as a result of the call - * @throws ClassCastException if the class of the specified element - * is incompatible with this deque (optional) - * @throws NullPointerException if the specified element is null (optional) - */ - boolean remove(Object o); - - /** - * Returns <tt>true</tt> if this deque contains the specified element. - * More formally, returns <tt>true</tt> if and only if this deque contains - * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. - * - * @param o object to be checked for containment in this deque - * @return <tt>true</tt> if this deque contains the specified element - * @throws ClassCastException if the class of the specified element - * is incompatible with this deque (optional) - * @throws NullPointerException if the specified element is null (optional) - */ - public boolean contains(Object o); - - /** - * Returns the number of elements in this deque. - * - * @return the number of elements in this deque - */ - public int size(); - - /** - * Returns an iterator over the elements in this deque in proper sequence. - * The elements will be returned in order from first (head) to last (tail). - * - * @return an iterator over the elements in this deque in proper sequence - */ - Iterator<E> iterator(); - - // *** Stack methods *** - - /** - * Pushes an element onto the stack represented by this deque. In other - * words, inserts the element at the front of this deque unless it would - * violate capacity restrictions. - * - * <p>This method is equivalent to {@link #addFirst(Object) addFirst}. - * - * @throws IllegalStateException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException {@inheritDoc} - */ - void push(E e); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/BlockingQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/BlockingQueue.java deleted file mode 100644 index b47cc98..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/BlockingQueue.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -import java.util.Collection; -import java.util.Queue; - -/** - * A {@link java.util.Queue} that additionally supports operations - * that wait for the queue to become non-empty when retrieving an - * element, and wait for space to become available in the queue when - * storing an element. - * - * <p><tt>BlockingQueue</tt> methods come in four forms, with different ways - * of handling operations that cannot be satisfied immediately, but may be - * satisfied at some point in the future: - * one throws an exception, the second returns a special value (either - * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third - * blocks the current thread indefinitely until the operation can succeed, - * and the fourth blocks for only a given maximum time limit before giving - * up. These methods are summarized in the following table: - * - * <p> - * <table BORDER CELLPADDING=3 CELLSPACING=1> - * <tr> - * <td></td> - * <td ALIGN=CENTER><em>Throws exception</em></td> - * <td ALIGN=CENTER><em>Special value</em></td> - * <td ALIGN=CENTER><em>Blocks</em></td> - * <td ALIGN=CENTER><em>Times out</em></td> - * </tr> - * <tr> - * <td><b>Insert</b></td> - * <td>{@link #add add(e)}</td> - * <td>{@link #offer offer(e)}</td> - * <td>{@link #put put(e)}</td> - * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td> - * </tr> - * <tr> - * <td><b>Remove</b></td> - * <td>{@link #remove remove()}</td> - * <td>{@link #poll poll()}</td> - * <td>{@link #take take()}</td> - * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td> - * </tr> - * <tr> - * <td><b>Examine</b></td> - * <td>{@link #element element()}</td> - * <td>{@link #peek peek()}</td> - * <td><em>not applicable</em></td> - * <td><em>not applicable</em></td> - * </tr> - * </table> - * - * <p>A <tt>BlockingQueue</tt> does not accept <tt>null</tt> elements. - * Implementations throw <tt>NullPointerException</tt> on attempts - * to <tt>add</tt>, <tt>put</tt> or <tt>offer</tt> a <tt>null</tt>. A - * <tt>null</tt> is used as a sentinel value to indicate failure of - * <tt>poll</tt> operations. - * - * <p>A <tt>BlockingQueue</tt> may be capacity bounded. At any given - * time it may have a <tt>remainingCapacity</tt> beyond which no - * additional elements can be <tt>put</tt> without blocking. - * A <tt>BlockingQueue</tt> without any intrinsic capacity constraints always - * reports a remaining capacity of <tt>Integer.MAX_VALUE</tt>. - * - * <p> <tt>BlockingQueue</tt> implementations are designed to be used - * primarily for producer-consumer queues, but additionally support - * the {@link java.util.Collection} interface. So, for example, it is - * possible to remove an arbitrary element from a queue using - * <tt>remove(x)</tt>. However, such operations are in general - * <em>not</em> performed very efficiently, and are intended for only - * occasional use, such as when a queued message is cancelled. - * - * <p> <tt>BlockingQueue</tt> implementations are thread-safe. All - * queuing methods achieve their effects atomically using internal - * locks or other forms of concurrency control. However, the - * <em>bulk</em> Collection operations <tt>addAll</tt>, - * <tt>containsAll</tt>, <tt>retainAll</tt> and <tt>removeAll</tt> are - * <em>not</em> necessarily performed atomically unless specified - * otherwise in an implementation. So it is possible, for example, for - * <tt>addAll(c)</tt> to fail (throwing an exception) after adding - * only some of the elements in <tt>c</tt>. - * - * <p>A <tt>BlockingQueue</tt> does <em>not</em> intrinsically support - * any kind of "close" or "shutdown" operation to - * indicate that no more items will be added. The needs and usage of - * such features tend to be implementation-dependent. For example, a - * common tactic is for producers to insert special - * <em>end-of-stream</em> or <em>poison</em> objects, that are - * interpreted accordingly when taken by consumers. - * - * <p> - * Usage example, based on a typical producer-consumer scenario. - * Note that a <tt>BlockingQueue</tt> can safely be used with multiple - * producers and multiple consumers. - * <pre> - * class Producer implements Runnable { - * private final BlockingQueue queue; - * Producer(BlockingQueue q) { queue = q; } - * public void run() { - * try { - * while (true) { queue.put(produce()); } - * } catch (InterruptedException ex) { ... handle ...} - * } - * Object produce() { ... } - * } - * - * class Consumer implements Runnable { - * private final BlockingQueue queue; - * Consumer(BlockingQueue q) { queue = q; } - * public void run() { - * try { - * while (true) { consume(queue.take()); } - * } catch (InterruptedException ex) { ... handle ...} - * } - * void consume(Object x) { ... } - * } - * - * class Setup { - * void main() { - * BlockingQueue q = new SomeQueueImplementation(); - * Producer p = new Producer(q); - * Consumer c1 = new Consumer(q); - * Consumer c2 = new Consumer(q); - * new Thread(p).start(); - * new Thread(c1).start(); - * new Thread(c2).start(); - * } - * } - * </pre> - * - * <p>Memory consistency effects: As with other concurrent - * collections, actions in a thread prior to placing an object into a - * {@code BlockingQueue} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * actions subsequent to the access or removal of that element from - * the {@code BlockingQueue} in another thread. - * - * <p>This interface is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ -public interface BlockingQueue<E> extends Queue<E> { - /** - * Inserts the specified element into this queue if it is possible to do - * so immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an - * <tt>IllegalStateException</tt> if no space is currently available. - * When using a capacity-restricted queue, it is generally preferable to - * use {@link #offer(Object) offer}. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws IllegalStateException if the element cannot be added at this - * time due to capacity restrictions - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this queue - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this queue - */ - boolean add(E e); - - /** - * Inserts the specified element into this queue if it is possible to do - * so immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and <tt>false</tt> if no space is currently - * available. When using a capacity-restricted queue, this method is - * generally preferable to {@link #add}, which can fail to insert an - * element only by throwing an exception. - * - * @param e the element to add - * @return <tt>true</tt> if the element was added to this queue, else - * <tt>false</tt> - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this queue - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this queue - */ - boolean offer(E e); - - /** - * Inserts the specified element into this queue, waiting if necessary - * for space to become available. - * - * @param e the element to add - * @throws InterruptedException if interrupted while waiting - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this queue - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this queue - */ - void put(E e) throws InterruptedException; - - /** - * Inserts the specified element into this queue, waiting up to the - * specified wait time if necessary for space to become available. - * - * @param e the element to add - * @param timeout how long to wait before giving up, in units of - * <tt>unit</tt> - * @param unit a <tt>TimeUnit</tt> determining how to interpret the - * <tt>timeout</tt> parameter - * @return <tt>true</tt> if successful, or <tt>false</tt> if - * the specified waiting time elapses before space is available - * @throws InterruptedException if interrupted while waiting - * @throws ClassCastException if the class of the specified element - * prevents it from being added to this queue - * @throws NullPointerException if the specified element is null - * @throws IllegalArgumentException if some property of the specified - * element prevents it from being added to this queue - */ - boolean offer(E e, long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Retrieves and removes the head of this queue, waiting if necessary - * until an element becomes available. - * - * @return the head of this queue - * @throws InterruptedException if interrupted while waiting - */ - E take() throws InterruptedException; - - /** - * Retrieves and removes the head of this queue, waiting up to the - * specified wait time if necessary for an element to become available. - * - * @param timeout how long to wait before giving up, in units of - * <tt>unit</tt> - * @param unit a <tt>TimeUnit</tt> determining how to interpret the - * <tt>timeout</tt> parameter - * @return the head of this queue, or <tt>null</tt> if the - * specified waiting time elapses before an element is available - * @throws InterruptedException if interrupted while waiting - */ - E poll(long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Returns the number of additional elements that this queue can ideally - * (in the absence of memory or resource constraints) accept without - * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic - * limit. - * - * <p>Note that you <em>cannot</em> always tell if an attempt to insert - * an element will succeed by inspecting <tt>remainingCapacity</tt> - * because it may be the case that another thread is about to - * insert or remove an element. - * - * @return the remaining capacity - */ - int remainingCapacity(); - - /** - * Removes a single instance of the specified element from this queue, - * if it is present. More formally, removes an element <tt>e</tt> such - * that <tt>o.equals(e)</tt>, if this queue contains one or more such - * elements. - * Returns <tt>true</tt> if this queue contained the specified element - * (or equivalently, if this queue changed as a result of the call). - * - * @param o element to be removed from this queue, if present - * @return <tt>true</tt> if this queue changed as a result of the call - * @throws ClassCastException if the class of the specified element - * is incompatible with this queue (optional) - * @throws NullPointerException if the specified element is null (optional) - */ - boolean remove(Object o); - - /** - * Returns <tt>true</tt> if this queue contains the specified element. - * More formally, returns <tt>true</tt> if and only if this queue contains - * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. - * - * @param o object to be checked for containment in this queue - * @return <tt>true</tt> if this queue contains the specified element - * @throws ClassCastException if the class of the specified element - * is incompatible with this queue (optional) - * @throws NullPointerException if the specified element is null (optional) - */ - public boolean contains(Object o); - - /** - * Removes all available elements from this queue and adds them - * to the given collection. This operation may be more - * efficient than repeatedly polling this queue. A failure - * encountered while attempting to add elements to - * collection <tt>c</tt> may result in elements being in neither, - * either or both collections when the associated exception is - * thrown. Attempts to drain a queue to itself result in - * <tt>IllegalArgumentException</tt>. Further, the behavior of - * this operation is undefined if the specified collection is - * modified while the operation is in progress. - * - * @param c the collection to transfer elements into - * @return the number of elements transferred - * @throws UnsupportedOperationException if addition of elements - * is not supported by the specified collection - * @throws ClassCastException if the class of an element of this queue - * prevents it from being added to the specified collection - * @throws NullPointerException if the specified collection is null - * @throws IllegalArgumentException if the specified collection is this - * queue, or some property of an element of this queue prevents - * it from being added to the specified collection - */ - int drainTo(Collection<? super E> c); - - /** - * Removes at most the given number of available elements from - * this queue and adds them to the given collection. A failure - * encountered while attempting to add elements to - * collection <tt>c</tt> may result in elements being in neither, - * either or both collections when the associated exception is - * thrown. Attempts to drain a queue to itself result in - * <tt>IllegalArgumentException</tt>. Further, the behavior of - * this operation is undefined if the specified collection is - * modified while the operation is in progress. - * - * @param c the collection to transfer elements into - * @param maxElements the maximum number of elements to transfer - * @return the number of elements transferred - * @throws UnsupportedOperationException if addition of elements - * is not supported by the specified collection - * @throws ClassCastException if the class of an element of this queue - * prevents it from being added to the specified collection - * @throws NullPointerException if the specified collection is null - * @throws IllegalArgumentException if the specified collection is this - * queue, or some property of an element of this queue prevents - * it from being added to the specified collection - */ - int drainTo(Collection<? super E> c, int maxElements); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/BrokenBarrierException.java b/libjava/classpath/external/jsr166/java/util/concurrent/BrokenBarrierException.java deleted file mode 100644 index 3f93fbb..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/BrokenBarrierException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * Exception thrown when a thread tries to wait upon a barrier that is - * in a broken state, or which enters the broken state while the thread - * is waiting. - * - * @see CyclicBarrier - * - * @since 1.5 - * @author Doug Lea - * - */ -public class BrokenBarrierException extends Exception { - private static final long serialVersionUID = 7117394618823254244L; - - /** - * Constructs a <tt>BrokenBarrierException</tt> with no specified detail - * message. - */ - public BrokenBarrierException() {} - - /** - * Constructs a <tt>BrokenBarrierException</tt> with the specified - * detail message. - * - * @param message the detail message - */ - public BrokenBarrierException(String message) { - super(message); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Callable.java b/libjava/classpath/external/jsr166/java/util/concurrent/Callable.java deleted file mode 100644 index abc4d04..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/Callable.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A task that returns a result and may throw an exception. - * Implementors define a single method with no arguments called - * <tt>call</tt>. - * - * <p>The <tt>Callable</tt> interface is similar to {@link - * java.lang.Runnable}, in that both are designed for classes whose - * instances are potentially executed by another thread. A - * <tt>Runnable</tt>, however, does not return a result and cannot - * throw a checked exception. - * - * <p> The {@link Executors} class contains utility methods to - * convert from other common forms to <tt>Callable</tt> classes. - * - * @see Executor - * @since 1.5 - * @author Doug Lea - * @param <V> the result type of method <tt>call</tt> - */ -public interface Callable<V> { - /** - * Computes a result, or throws an exception if unable to do so. - * - * @return computed result - * @throws Exception if unable to compute a result - */ - V call() throws Exception; -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CancellationException.java b/libjava/classpath/external/jsr166/java/util/concurrent/CancellationException.java deleted file mode 100644 index 2c29544..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/CancellationException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * Exception indicating that the result of a value-producing task, - * such as a {@link FutureTask}, cannot be retrieved because the task - * was cancelled. - * - * @since 1.5 - * @author Doug Lea - */ -public class CancellationException extends IllegalStateException { - private static final long serialVersionUID = -9202173006928992231L; - - /** - * Constructs a <tt>CancellationException</tt> with no detail message. - */ - public CancellationException() {} - - /** - * Constructs a <tt>CancellationException</tt> with the specified detail - * message. - * - * @param message the detail message - */ - public CancellationException(String message) { - super(message); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CompletionService.java b/libjava/classpath/external/jsr166/java/util/concurrent/CompletionService.java deleted file mode 100644 index df9f719..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/CompletionService.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A service that decouples the production of new asynchronous tasks - * from the consumption of the results of completed tasks. Producers - * <tt>submit</tt> tasks for execution. Consumers <tt>take</tt> - * completed tasks and process their results in the order they - * complete. A <tt>CompletionService</tt> can for example be used to - * manage asynchronous IO, in which tasks that perform reads are - * submitted in one part of a program or system, and then acted upon - * in a different part of the program when the reads complete, - * possibly in a different order than they were requested. - * - * <p>Typically, a <tt>CompletionService</tt> relies on a separate - * {@link Executor} to actually execute the tasks, in which case the - * <tt>CompletionService</tt> only manages an internal completion - * queue. The {@link ExecutorCompletionService} class provides an - * implementation of this approach. - * - * <p>Memory consistency effects: Actions in a thread prior to - * submitting a task to a {@code CompletionService} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * actions taken by that task, which in turn <i>happen-before</i> - * actions following a successful return from the corresponding {@code take()}. - * - */ -public interface CompletionService<V> { - /** - * Submits a value-returning task for execution and returns a Future - * representing the pending results of the task. Upon completion, - * this task may be taken or polled. - * - * @param task the task to submit - * @return a Future representing pending completion of the task - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if the task is null - */ - Future<V> submit(Callable<V> task); - - /** - * Submits a Runnable task for execution and returns a Future - * representing that task. Upon completion, this task may be - * taken or polled. - * - * @param task the task to submit - * @param result the result to return upon successful completion - * @return a Future representing pending completion of the task, - * and whose <tt>get()</tt> method will return the given - * result value upon completion - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if the task is null - */ - Future<V> submit(Runnable task, V result); - - /** - * Retrieves and removes the Future representing the next - * completed task, waiting if none are yet present. - * - * @return the Future representing the next completed task - * @throws InterruptedException if interrupted while waiting - */ - Future<V> take() throws InterruptedException; - - - /** - * Retrieves and removes the Future representing the next - * completed task or <tt>null</tt> if none are present. - * - * @return the Future representing the next completed task, or - * <tt>null</tt> if none are present - */ - Future<V> poll(); - - /** - * Retrieves and removes the Future representing the next - * completed task, waiting if necessary up to the specified wait - * time if none are yet present. - * - * @param timeout how long to wait before giving up, in units of - * <tt>unit</tt> - * @param unit a <tt>TimeUnit</tt> determining how to interpret the - * <tt>timeout</tt> parameter - * @return the Future representing the next completed task or - * <tt>null</tt> if the specified waiting time elapses - * before one is present - * @throws InterruptedException if interrupted while waiting - */ - Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException; -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentHashMap.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentHashMap.java deleted file mode 100644 index 9ad9ab2..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentHashMap.java +++ /dev/null @@ -1,1277 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.locks.*; -import java.util.*; -import java.io.Serializable; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -/** - * A hash table supporting full concurrency of retrievals and - * adjustable expected concurrency for updates. This class obeys the - * same functional specification as {@link java.util.Hashtable}, and - * includes versions of methods corresponding to each method of - * <tt>Hashtable</tt>. However, even though all operations are - * thread-safe, retrieval operations do <em>not</em> entail locking, - * and there is <em>not</em> any support for locking the entire table - * in a way that prevents all access. This class is fully - * interoperable with <tt>Hashtable</tt> in programs that rely on its - * thread safety but not on its synchronization details. - * - * <p> Retrieval operations (including <tt>get</tt>) generally do not - * block, so may overlap with update operations (including - * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results - * of the most recently <em>completed</em> update operations holding - * upon their onset. For aggregate operations such as <tt>putAll</tt> - * and <tt>clear</tt>, concurrent retrievals may reflect insertion or - * removal of only some entries. Similarly, Iterators and - * Enumerations return elements reflecting the state of the hash table - * at some point at or since the creation of the iterator/enumeration. - * They do <em>not</em> throw {@link ConcurrentModificationException}. - * However, iterators are designed to be used by only one thread at a time. - * - * <p> The allowed concurrency among update operations is guided by - * the optional <tt>concurrencyLevel</tt> constructor argument - * (default <tt>16</tt>), which is used as a hint for internal sizing. The - * table is internally partitioned to try to permit the indicated - * number of concurrent updates without contention. Because placement - * in hash tables is essentially random, the actual concurrency will - * vary. Ideally, you should choose a value to accommodate as many - * threads as will ever concurrently modify the table. Using a - * significantly higher value than you need can waste space and time, - * and a significantly lower value can lead to thread contention. But - * overestimates and underestimates within an order of magnitude do - * not usually have much noticeable impact. A value of one is - * appropriate when it is known that only one thread will modify and - * all others will only read. Also, resizing this or any other kind of - * hash table is a relatively slow operation, so, when possible, it is - * a good idea to provide estimates of expected table sizes in - * constructors. - * - * <p>This class and its views and iterators implement all of the - * <em>optional</em> methods of the {@link Map} and {@link Iterator} - * interfaces. - * - * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class - * does <em>not</em> allow <tt>null</tt> to be used as a key or value. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <K> the type of keys maintained by this map - * @param <V> the type of mapped values - */ -public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> - implements ConcurrentMap<K, V>, Serializable { - private static final long serialVersionUID = 7249069246763182397L; - - /* - * The basic strategy is to subdivide the table among Segments, - * each of which itself is a concurrently readable hash table. - */ - - /* ---------------- Constants -------------- */ - - /** - * The default initial capacity for this table, - * used when not otherwise specified in a constructor. - */ - static final int DEFAULT_INITIAL_CAPACITY = 16; - - /** - * The default load factor for this table, used when not - * otherwise specified in a constructor. - */ - static final float DEFAULT_LOAD_FACTOR = 0.75f; - - /** - * The default concurrency level for this table, used when not - * otherwise specified in a constructor. - */ - static final int DEFAULT_CONCURRENCY_LEVEL = 16; - - /** - * The maximum capacity, used if a higher value is implicitly - * specified by either of the constructors with arguments. MUST - * be a power of two <= 1<<30 to ensure that entries are indexable - * using ints. - */ - static final int MAXIMUM_CAPACITY = 1 << 30; - - /** - * The maximum number of segments to allow; used to bound - * constructor arguments. - */ - static final int MAX_SEGMENTS = 1 << 16; // slightly conservative - - /** - * Number of unsynchronized retries in size and containsValue - * methods before resorting to locking. This is used to avoid - * unbounded retries if tables undergo continuous modification - * which would make it impossible to obtain an accurate result. - */ - static final int RETRIES_BEFORE_LOCK = 2; - - /* ---------------- Fields -------------- */ - - /** - * Mask value for indexing into segments. The upper bits of a - * key's hash code are used to choose the segment. - */ - final int segmentMask; - - /** - * Shift value for indexing within segments. - */ - final int segmentShift; - - /** - * The segments, each of which is a specialized hash table - */ - final Segment<K,V>[] segments; - - transient Set<K> keySet; - transient Set<Map.Entry<K,V>> entrySet; - transient Collection<V> values; - - /* ---------------- Small Utilities -------------- */ - - /** - * Applies a supplemental hash function to a given hashCode, which - * defends against poor quality hash functions. This is critical - * because ConcurrentHashMap uses power-of-two length hash tables, - * that otherwise encounter collisions for hashCodes that do not - * differ in lower bits. - */ - private static int hash(int h) { - // This function ensures that hashCodes that differ only by - // constant multiples at each bit position have a bounded - // number of collisions (approximately 8 at default load factor). - h ^= (h >>> 20) ^ (h >>> 12); - return h ^ (h >>> 7) ^ (h >>> 4); - } - - /** - * Returns the segment that should be used for key with given hash - * @param hash the hash code for the key - * @return the segment - */ - final Segment<K,V> segmentFor(int hash) { - return segments[(hash >>> segmentShift) & segmentMask]; - } - - /* ---------------- Inner Classes -------------- */ - - /** - * ConcurrentHashMap list entry. Note that this is never exported - * out as a user-visible Map.Entry. - * - * Because the value field is volatile, not final, it is legal wrt - * the Java Memory Model for an unsynchronized reader to see null - * instead of initial value when read via a data race. Although a - * reordering leading to this is not likely to ever actually - * occur, the Segment.readValueUnderLock method is used as a - * backup in case a null (pre-initialized) value is ever seen in - * an unsynchronized access method. - */ - static final class HashEntry<K,V> { - final K key; - final int hash; - volatile V value; - final HashEntry<K,V> next; - - HashEntry(K key, int hash, HashEntry<K,V> next, V value) { - this.key = key; - this.hash = hash; - this.next = next; - this.value = value; - } - - @SuppressWarnings("unchecked") - static final <K,V> HashEntry<K,V>[] newArray(int i) { - return new HashEntry[i]; - } - } - - /** - * Segments are specialized versions of hash tables. This - * subclasses from ReentrantLock opportunistically, just to - * simplify some locking and avoid separate construction. - */ - static final class Segment<K,V> extends ReentrantLock implements Serializable { - /* - * Segments maintain a table of entry lists that are ALWAYS - * kept in a consistent state, so can be read without locking. - * Next fields of nodes are immutable (final). All list - * additions are performed at the front of each bin. This - * makes it easy to check changes, and also fast to traverse. - * When nodes would otherwise be changed, new nodes are - * created to replace them. This works well for hash tables - * since the bin lists tend to be short. (The average length - * is less than two for the default load factor threshold.) - * - * Read operations can thus proceed without locking, but rely - * on selected uses of volatiles to ensure that completed - * write operations performed by other threads are - * noticed. For most purposes, the "count" field, tracking the - * number of elements, serves as that volatile variable - * ensuring visibility. This is convenient because this field - * needs to be read in many read operations anyway: - * - * - All (unsynchronized) read operations must first read the - * "count" field, and should not look at table entries if - * it is 0. - * - * - All (synchronized) write operations should write to - * the "count" field after structurally changing any bin. - * The operations must not take any action that could even - * momentarily cause a concurrent read operation to see - * inconsistent data. This is made easier by the nature of - * the read operations in Map. For example, no operation - * can reveal that the table has grown but the threshold - * has not yet been updated, so there are no atomicity - * requirements for this with respect to reads. - * - * As a guide, all critical volatile reads and writes to the - * count field are marked in code comments. - */ - - private static final long serialVersionUID = 2249069246763182397L; - - /** - * The number of elements in this segment's region. - */ - transient volatile int count; - - /** - * Number of updates that alter the size of the table. This is - * used during bulk-read methods to make sure they see a - * consistent snapshot: If modCounts change during a traversal - * of segments computing size or checking containsValue, then - * we might have an inconsistent view of state so (usually) - * must retry. - */ - transient int modCount; - - /** - * The table is rehashed when its size exceeds this threshold. - * (The value of this field is always <tt>(int)(capacity * - * loadFactor)</tt>.) - */ - transient int threshold; - - /** - * The per-segment table. - */ - transient volatile HashEntry<K,V>[] table; - - /** - * The load factor for the hash table. Even though this value - * is same for all segments, it is replicated to avoid needing - * links to outer object. - * @serial - */ - final float loadFactor; - - Segment(int initialCapacity, float lf) { - loadFactor = lf; - setTable(HashEntry.<K,V>newArray(initialCapacity)); - } - - @SuppressWarnings("unchecked") - static final <K,V> Segment<K,V>[] newArray(int i) { - return new Segment[i]; - } - - /** - * Sets table to new HashEntry array. - * Call only while holding lock or in constructor. - */ - void setTable(HashEntry<K,V>[] newTable) { - threshold = (int)(newTable.length * loadFactor); - table = newTable; - } - - /** - * Returns properly casted first entry of bin for given hash. - */ - HashEntry<K,V> getFirst(int hash) { - HashEntry<K,V>[] tab = table; - return tab[hash & (tab.length - 1)]; - } - - /** - * Reads value field of an entry under lock. Called if value - * field ever appears to be null. This is possible only if a - * compiler happens to reorder a HashEntry initialization with - * its table assignment, which is legal under memory model - * but is not known to ever occur. - */ - V readValueUnderLock(HashEntry<K,V> e) { - lock(); - try { - return e.value; - } finally { - unlock(); - } - } - - /* Specialized implementations of map methods */ - - V get(Object key, int hash) { - if (count != 0) { // read-volatile - HashEntry<K,V> e = getFirst(hash); - while (e != null) { - if (e.hash == hash && key.equals(e.key)) { - V v = e.value; - if (v != null) - return v; - return readValueUnderLock(e); // recheck - } - e = e.next; - } - } - return null; - } - - boolean containsKey(Object key, int hash) { - if (count != 0) { // read-volatile - HashEntry<K,V> e = getFirst(hash); - while (e != null) { - if (e.hash == hash && key.equals(e.key)) - return true; - e = e.next; - } - } - return false; - } - - boolean containsValue(Object value) { - if (count != 0) { // read-volatile - HashEntry<K,V>[] tab = table; - int len = tab.length; - for (int i = 0 ; i < len; i++) { - for (HashEntry<K,V> e = tab[i]; e != null; e = e.next) { - V v = e.value; - if (v == null) // recheck - v = readValueUnderLock(e); - if (value.equals(v)) - return true; - } - } - } - return false; - } - - boolean replace(K key, int hash, V oldValue, V newValue) { - lock(); - try { - HashEntry<K,V> e = getFirst(hash); - while (e != null && (e.hash != hash || !key.equals(e.key))) - e = e.next; - - boolean replaced = false; - if (e != null && oldValue.equals(e.value)) { - replaced = true; - e.value = newValue; - } - return replaced; - } finally { - unlock(); - } - } - - V replace(K key, int hash, V newValue) { - lock(); - try { - HashEntry<K,V> e = getFirst(hash); - while (e != null && (e.hash != hash || !key.equals(e.key))) - e = e.next; - - V oldValue = null; - if (e != null) { - oldValue = e.value; - e.value = newValue; - } - return oldValue; - } finally { - unlock(); - } - } - - - V put(K key, int hash, V value, boolean onlyIfAbsent) { - lock(); - try { - int c = count; - if (c++ > threshold) // ensure capacity - rehash(); - HashEntry<K,V>[] tab = table; - int index = hash & (tab.length - 1); - HashEntry<K,V> first = tab[index]; - HashEntry<K,V> e = first; - while (e != null && (e.hash != hash || !key.equals(e.key))) - e = e.next; - - V oldValue; - if (e != null) { - oldValue = e.value; - if (!onlyIfAbsent) - e.value = value; - } - else { - oldValue = null; - ++modCount; - tab[index] = new HashEntry<K,V>(key, hash, first, value); - count = c; // write-volatile - } - return oldValue; - } finally { - unlock(); - } - } - - void rehash() { - HashEntry<K,V>[] oldTable = table; - int oldCapacity = oldTable.length; - if (oldCapacity >= MAXIMUM_CAPACITY) - return; - - /* - * Reclassify nodes in each list to new Map. Because we are - * using power-of-two expansion, the elements from each bin - * must either stay at same index, or move with a power of two - * offset. We eliminate unnecessary node creation by catching - * cases where old nodes can be reused because their next - * fields won't change. Statistically, at the default - * threshold, only about one-sixth of them need cloning when - * a table doubles. The nodes they replace will be garbage - * collectable as soon as they are no longer referenced by any - * reader thread that may be in the midst of traversing table - * right now. - */ - - HashEntry<K,V>[] newTable = HashEntry.newArray(oldCapacity<<1); - threshold = (int)(newTable.length * loadFactor); - int sizeMask = newTable.length - 1; - for (int i = 0; i < oldCapacity ; i++) { - // We need to guarantee that any existing reads of old Map can - // proceed. So we cannot yet null out each bin. - HashEntry<K,V> e = oldTable[i]; - - if (e != null) { - HashEntry<K,V> next = e.next; - int idx = e.hash & sizeMask; - - // Single node on list - if (next == null) - newTable[idx] = e; - - else { - // Reuse trailing consecutive sequence at same slot - HashEntry<K,V> lastRun = e; - int lastIdx = idx; - for (HashEntry<K,V> last = next; - last != null; - last = last.next) { - int k = last.hash & sizeMask; - if (k != lastIdx) { - lastIdx = k; - lastRun = last; - } - } - newTable[lastIdx] = lastRun; - - // Clone all remaining nodes - for (HashEntry<K,V> p = e; p != lastRun; p = p.next) { - int k = p.hash & sizeMask; - HashEntry<K,V> n = newTable[k]; - newTable[k] = new HashEntry<K,V>(p.key, p.hash, - n, p.value); - } - } - } - } - table = newTable; - } - - /** - * Remove; match on key only if value null, else match both. - */ - V remove(Object key, int hash, Object value) { - lock(); - try { - int c = count - 1; - HashEntry<K,V>[] tab = table; - int index = hash & (tab.length - 1); - HashEntry<K,V> first = tab[index]; - HashEntry<K,V> e = first; - while (e != null && (e.hash != hash || !key.equals(e.key))) - e = e.next; - - V oldValue = null; - if (e != null) { - V v = e.value; - if (value == null || value.equals(v)) { - oldValue = v; - // All entries following removed node can stay - // in list, but all preceding ones need to be - // cloned. - ++modCount; - HashEntry<K,V> newFirst = e.next; - for (HashEntry<K,V> p = first; p != e; p = p.next) - newFirst = new HashEntry<K,V>(p.key, p.hash, - newFirst, p.value); - tab[index] = newFirst; - count = c; // write-volatile - } - } - return oldValue; - } finally { - unlock(); - } - } - - void clear() { - if (count != 0) { - lock(); - try { - HashEntry<K,V>[] tab = table; - for (int i = 0; i < tab.length ; i++) - tab[i] = null; - ++modCount; - count = 0; // write-volatile - } finally { - unlock(); - } - } - } - } - - - - /* ---------------- Public operations -------------- */ - - /** - * Creates a new, empty map with the specified initial - * capacity, load factor and concurrency level. - * - * @param initialCapacity the initial capacity. The implementation - * performs internal sizing to accommodate this many elements. - * @param loadFactor the load factor threshold, used to control resizing. - * Resizing may be performed when the average number of elements per - * bin exceeds this threshold. - * @param concurrencyLevel the estimated number of concurrently - * updating threads. The implementation performs internal sizing - * to try to accommodate this many threads. - * @throws IllegalArgumentException if the initial capacity is - * negative or the load factor or concurrencyLevel are - * nonpositive. - */ - public ConcurrentHashMap(int initialCapacity, - float loadFactor, int concurrencyLevel) { - if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) - throw new IllegalArgumentException(); - - if (concurrencyLevel > MAX_SEGMENTS) - concurrencyLevel = MAX_SEGMENTS; - - // Find power-of-two sizes best matching arguments - int sshift = 0; - int ssize = 1; - while (ssize < concurrencyLevel) { - ++sshift; - ssize <<= 1; - } - segmentShift = 32 - sshift; - segmentMask = ssize - 1; - this.segments = Segment.newArray(ssize); - - if (initialCapacity > MAXIMUM_CAPACITY) - initialCapacity = MAXIMUM_CAPACITY; - int c = initialCapacity / ssize; - if (c * ssize < initialCapacity) - ++c; - int cap = 1; - while (cap < c) - cap <<= 1; - - for (int i = 0; i < this.segments.length; ++i) - this.segments[i] = new Segment<K,V>(cap, loadFactor); - } - - /** - * Creates a new, empty map with the specified initial capacity - * and load factor and with the default concurrencyLevel (16). - * - * @param initialCapacity The implementation performs internal - * sizing to accommodate this many elements. - * @param loadFactor the load factor threshold, used to control resizing. - * Resizing may be performed when the average number of elements per - * bin exceeds this threshold. - * @throws IllegalArgumentException if the initial capacity of - * elements is negative or the load factor is nonpositive - * - * @since 1.6 - */ - public ConcurrentHashMap(int initialCapacity, float loadFactor) { - this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL); - } - - /** - * Creates a new, empty map with the specified initial capacity, - * and with default load factor (0.75) and concurrencyLevel (16). - * - * @param initialCapacity the initial capacity. The implementation - * performs internal sizing to accommodate this many elements. - * @throws IllegalArgumentException if the initial capacity of - * elements is negative. - */ - public ConcurrentHashMap(int initialCapacity) { - this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); - } - - /** - * Creates a new, empty map with a default initial capacity (16), - * load factor (0.75) and concurrencyLevel (16). - */ - public ConcurrentHashMap() { - this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); - } - - /** - * Creates a new map with the same mappings as the given map. - * The map is created with a capacity of 1.5 times the number - * of mappings in the given map or 16 (whichever is greater), - * and a default load factor (0.75) and concurrencyLevel (16). - * - * @param m the map - */ - public ConcurrentHashMap(Map<? extends K, ? extends V> m) { - this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, - DEFAULT_INITIAL_CAPACITY), - DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); - putAll(m); - } - - /** - * Returns <tt>true</tt> if this map contains no key-value mappings. - * - * @return <tt>true</tt> if this map contains no key-value mappings - */ - public boolean isEmpty() { - final Segment<K,V>[] segments = this.segments; - /* - * We keep track of per-segment modCounts to avoid ABA - * problems in which an element in one segment was added and - * in another removed during traversal, in which case the - * table was never actually empty at any point. Note the - * similar use of modCounts in the size() and containsValue() - * methods, which are the only other methods also susceptible - * to ABA problems. - */ - int[] mc = new int[segments.length]; - int mcsum = 0; - for (int i = 0; i < segments.length; ++i) { - if (segments[i].count != 0) - return false; - else - mcsum += mc[i] = segments[i].modCount; - } - // If mcsum happens to be zero, then we know we got a snapshot - // before any modifications at all were made. This is - // probably common enough to bother tracking. - if (mcsum != 0) { - for (int i = 0; i < segments.length; ++i) { - if (segments[i].count != 0 || - mc[i] != segments[i].modCount) - return false; - } - } - return true; - } - - /** - * Returns the number of key-value mappings in this map. If the - * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns - * <tt>Integer.MAX_VALUE</tt>. - * - * @return the number of key-value mappings in this map - */ - public int size() { - final Segment<K,V>[] segments = this.segments; - long sum = 0; - long check = 0; - int[] mc = new int[segments.length]; - // Try a few times to get accurate count. On failure due to - // continuous async changes in table, resort to locking. - for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) { - check = 0; - sum = 0; - int mcsum = 0; - for (int i = 0; i < segments.length; ++i) { - sum += segments[i].count; - mcsum += mc[i] = segments[i].modCount; - } - if (mcsum != 0) { - for (int i = 0; i < segments.length; ++i) { - check += segments[i].count; - if (mc[i] != segments[i].modCount) { - check = -1; // force retry - break; - } - } - } - if (check == sum) - break; - } - if (check != sum) { // Resort to locking all segments - sum = 0; - for (int i = 0; i < segments.length; ++i) - segments[i].lock(); - for (int i = 0; i < segments.length; ++i) - sum += segments[i].count; - for (int i = 0; i < segments.length; ++i) - segments[i].unlock(); - } - if (sum > Integer.MAX_VALUE) - return Integer.MAX_VALUE; - else - return (int)sum; - } - - /** - * Returns the value to which the specified key is mapped, - * or {@code null} if this map contains no mapping for the key. - * - * <p>More formally, if this map contains a mapping from a key - * {@code k} to a value {@code v} such that {@code key.equals(k)}, - * then this method returns {@code v}; otherwise it returns - * {@code null}. (There can be at most one such mapping.) - * - * @throws NullPointerException if the specified key is null - */ - public V get(Object key) { - int hash = hash(key.hashCode()); - return segmentFor(hash).get(key, hash); - } - - /** - * Tests if the specified object is a key in this table. - * - * @param key possible key - * @return <tt>true</tt> if and only if the specified object - * is a key in this table, as determined by the - * <tt>equals</tt> method; <tt>false</tt> otherwise. - * @throws NullPointerException if the specified key is null - */ - public boolean containsKey(Object key) { - int hash = hash(key.hashCode()); - return segmentFor(hash).containsKey(key, hash); - } - - /** - * Returns <tt>true</tt> if this map maps one or more keys to the - * specified value. Note: This method requires a full internal - * traversal of the hash table, and so is much slower than - * method <tt>containsKey</tt>. - * - * @param value value whose presence in this map is to be tested - * @return <tt>true</tt> if this map maps one or more keys to the - * specified value - * @throws NullPointerException if the specified value is null - */ - public boolean containsValue(Object value) { - if (value == null) - throw new NullPointerException(); - - // See explanation of modCount use above - - final Segment<K,V>[] segments = this.segments; - int[] mc = new int[segments.length]; - - // Try a few times without locking - for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) { - int sum = 0; - int mcsum = 0; - for (int i = 0; i < segments.length; ++i) { - int c = segments[i].count; - mcsum += mc[i] = segments[i].modCount; - if (segments[i].containsValue(value)) - return true; - } - boolean cleanSweep = true; - if (mcsum != 0) { - for (int i = 0; i < segments.length; ++i) { - int c = segments[i].count; - if (mc[i] != segments[i].modCount) { - cleanSweep = false; - break; - } - } - } - if (cleanSweep) - return false; - } - // Resort to locking all segments - for (int i = 0; i < segments.length; ++i) - segments[i].lock(); - boolean found = false; - try { - for (int i = 0; i < segments.length; ++i) { - if (segments[i].containsValue(value)) { - found = true; - break; - } - } - } finally { - for (int i = 0; i < segments.length; ++i) - segments[i].unlock(); - } - return found; - } - - /** - * Legacy method testing if some key maps into the specified value - * in this table. This method is identical in functionality to - * {@link #containsValue}, and exists solely to ensure - * full compatibility with class {@link java.util.Hashtable}, - * which supported this method prior to introduction of the - * Java Collections framework. - - * @param value a value to search for - * @return <tt>true</tt> if and only if some key maps to the - * <tt>value</tt> argument in this table as - * determined by the <tt>equals</tt> method; - * <tt>false</tt> otherwise - * @throws NullPointerException if the specified value is null - */ - public boolean contains(Object value) { - return containsValue(value); - } - - /** - * Maps the specified key to the specified value in this table. - * Neither the key nor the value can be null. - * - * <p> The value can be retrieved by calling the <tt>get</tt> method - * with a key that is equal to the original key. - * - * @param key key with which the specified value is to be associated - * @param value value to be associated with the specified key - * @return the previous value associated with <tt>key</tt>, or - * <tt>null</tt> if there was no mapping for <tt>key</tt> - * @throws NullPointerException if the specified key or value is null - */ - public V put(K key, V value) { - if (value == null) - throw new NullPointerException(); - int hash = hash(key.hashCode()); - return segmentFor(hash).put(key, hash, value, false); - } - - /** - * {@inheritDoc} - * - * @return the previous value associated with the specified key, - * or <tt>null</tt> if there was no mapping for the key - * @throws NullPointerException if the specified key or value is null - */ - public V putIfAbsent(K key, V value) { - if (value == null) - throw new NullPointerException(); - int hash = hash(key.hashCode()); - return segmentFor(hash).put(key, hash, value, true); - } - - /** - * Copies all of the mappings from the specified map to this one. - * These mappings replace any mappings that this map had for any of the - * keys currently in the specified map. - * - * @param m mappings to be stored in this map - */ - public void putAll(Map<? extends K, ? extends V> m) { - for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) - put(e.getKey(), e.getValue()); - } - - /** - * Removes the key (and its corresponding value) from this map. - * This method does nothing if the key is not in the map. - * - * @param key the key that needs to be removed - * @return the previous value associated with <tt>key</tt>, or - * <tt>null</tt> if there was no mapping for <tt>key</tt> - * @throws NullPointerException if the specified key is null - */ - public V remove(Object key) { - int hash = hash(key.hashCode()); - return segmentFor(hash).remove(key, hash, null); - } - - /** - * {@inheritDoc} - * - * @throws NullPointerException if the specified key is null - */ - public boolean remove(Object key, Object value) { - int hash = hash(key.hashCode()); - if (value == null) - return false; - return segmentFor(hash).remove(key, hash, value) != null; - } - - /** - * {@inheritDoc} - * - * @throws NullPointerException if any of the arguments are null - */ - public boolean replace(K key, V oldValue, V newValue) { - if (oldValue == null || newValue == null) - throw new NullPointerException(); - int hash = hash(key.hashCode()); - return segmentFor(hash).replace(key, hash, oldValue, newValue); - } - - /** - * {@inheritDoc} - * - * @return the previous value associated with the specified key, - * or <tt>null</tt> if there was no mapping for the key - * @throws NullPointerException if the specified key or value is null - */ - public V replace(K key, V value) { - if (value == null) - throw new NullPointerException(); - int hash = hash(key.hashCode()); - return segmentFor(hash).replace(key, hash, value); - } - - /** - * Removes all of the mappings from this map. - */ - public void clear() { - for (int i = 0; i < segments.length; ++i) - segments[i].clear(); - } - - /** - * Returns a {@link Set} view of the keys contained in this map. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from this map, - * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, - * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> - * operations. It does not support the <tt>add</tt> or - * <tt>addAll</tt> operations. - * - * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator - * that will never throw {@link 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. - */ - public Set<K> keySet() { - Set<K> ks = keySet; - return (ks != null) ? ks : (keySet = new KeySet()); - } - - /** - * Returns a {@link Collection} view of the values contained in this map. - * The collection is backed by the map, so changes to the map are - * reflected in the collection, and vice-versa. The collection - * supports element removal, which removes the corresponding - * mapping from this map, via the <tt>Iterator.remove</tt>, - * <tt>Collection.remove</tt>, <tt>removeAll</tt>, - * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not - * support the <tt>add</tt> or <tt>addAll</tt> operations. - * - * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator - * that will never throw {@link 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. - */ - public Collection<V> values() { - Collection<V> vs = values; - return (vs != null) ? vs : (values = new Values()); - } - - /** - * Returns a {@link Set} view of the mappings contained in this map. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from the map, - * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, - * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> - * operations. It does not support the <tt>add</tt> or - * <tt>addAll</tt> operations. - * - * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator - * that will never throw {@link 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. - */ - public Set<Map.Entry<K,V>> entrySet() { - Set<Map.Entry<K,V>> es = entrySet; - return (es != null) ? es : (entrySet = new EntrySet()); - } - - /** - * Returns an enumeration of the keys in this table. - * - * @return an enumeration of the keys in this table - * @see #keySet - */ - public Enumeration<K> keys() { - return new KeyIterator(); - } - - /** - * Returns an enumeration of the values in this table. - * - * @return an enumeration of the values in this table - * @see #values - */ - public Enumeration<V> elements() { - return new ValueIterator(); - } - - /* ---------------- Iterator Support -------------- */ - - abstract class HashIterator { - int nextSegmentIndex; - int nextTableIndex; - HashEntry<K,V>[] currentTable; - HashEntry<K, V> nextEntry; - HashEntry<K, V> lastReturned; - - HashIterator() { - nextSegmentIndex = segments.length - 1; - nextTableIndex = -1; - advance(); - } - - public boolean hasMoreElements() { return hasNext(); } - - final void advance() { - if (nextEntry != null && (nextEntry = nextEntry.next) != null) - return; - - while (nextTableIndex >= 0) { - if ( (nextEntry = currentTable[nextTableIndex--]) != null) - return; - } - - while (nextSegmentIndex >= 0) { - Segment<K,V> seg = segments[nextSegmentIndex--]; - if (seg.count != 0) { - currentTable = seg.table; - for (int j = currentTable.length - 1; j >= 0; --j) { - if ( (nextEntry = currentTable[j]) != null) { - nextTableIndex = j - 1; - return; - } - } - } - } - } - - public boolean hasNext() { return nextEntry != null; } - - HashEntry<K,V> nextEntry() { - if (nextEntry == null) - throw new NoSuchElementException(); - lastReturned = nextEntry; - advance(); - return lastReturned; - } - - public void remove() { - if (lastReturned == null) - throw new IllegalStateException(); - ConcurrentHashMap.this.remove(lastReturned.key); - lastReturned = null; - } - } - - final class KeyIterator - extends HashIterator - implements Iterator<K>, Enumeration<K> - { - public K next() { return super.nextEntry().key; } - public K nextElement() { return super.nextEntry().key; } - } - - final class ValueIterator - extends HashIterator - implements Iterator<V>, Enumeration<V> - { - public V next() { return super.nextEntry().value; } - public V nextElement() { return super.nextEntry().value; } - } - - /** - * Custom Entry class used by EntryIterator.next(), that relays - * setValue changes to the underlying map. - */ - final class WriteThroughEntry - extends AbstractMap.SimpleEntry<K,V> - { - WriteThroughEntry(K k, V v) { - super(k,v); - } - - /** - * Set our entry's value and write through to the map. The - * value to return is somewhat arbitrary here. Since a - * WriteThroughEntry does not necessarily track asynchronous - * changes, the most recent "previous" value could be - * different from what we return (or could even have been - * removed in which case the put will re-establish). We do not - * and cannot guarantee more. - */ - public V setValue(V value) { - if (value == null) throw new NullPointerException(); - V v = super.setValue(value); - ConcurrentHashMap.this.put(getKey(), value); - return v; - } - } - - final class EntryIterator - extends HashIterator - implements Iterator<Entry<K,V>> - { - public Map.Entry<K,V> next() { - HashEntry<K,V> e = super.nextEntry(); - return new WriteThroughEntry(e.key, e.value); - } - } - - final class KeySet extends AbstractSet<K> { - public Iterator<K> iterator() { - return new KeyIterator(); - } - public int size() { - return ConcurrentHashMap.this.size(); - } - public boolean contains(Object o) { - return ConcurrentHashMap.this.containsKey(o); - } - public boolean remove(Object o) { - return ConcurrentHashMap.this.remove(o) != null; - } - public void clear() { - ConcurrentHashMap.this.clear(); - } - } - - final class Values extends AbstractCollection<V> { - public Iterator<V> iterator() { - return new ValueIterator(); - } - public int size() { - return ConcurrentHashMap.this.size(); - } - public boolean contains(Object o) { - return ConcurrentHashMap.this.containsValue(o); - } - public void clear() { - ConcurrentHashMap.this.clear(); - } - } - - final class EntrySet extends AbstractSet<Map.Entry<K,V>> { - public Iterator<Map.Entry<K,V>> iterator() { - return new EntryIterator(); - } - public boolean contains(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry<?,?> e = (Map.Entry<?,?>)o; - V v = ConcurrentHashMap.this.get(e.getKey()); - return v != null && v.equals(e.getValue()); - } - public boolean remove(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry<?,?> e = (Map.Entry<?,?>)o; - return ConcurrentHashMap.this.remove(e.getKey(), e.getValue()); - } - public int size() { - return ConcurrentHashMap.this.size(); - } - public void clear() { - ConcurrentHashMap.this.clear(); - } - } - - /* ---------------- Serialization Support -------------- */ - - /** - * Save the state of the <tt>ConcurrentHashMap</tt> instance to a - * stream (i.e., serialize it). - * @param s the stream - * @serialData - * the key (Object) and value (Object) - * for each key-value mapping, followed by a null pair. - * The key-value mappings are emitted in no particular order. - */ - private void writeObject(java.io.ObjectOutputStream s) throws IOException { - s.defaultWriteObject(); - - for (int k = 0; k < segments.length; ++k) { - Segment<K,V> seg = segments[k]; - seg.lock(); - try { - HashEntry<K,V>[] tab = seg.table; - for (int i = 0; i < tab.length; ++i) { - for (HashEntry<K,V> e = tab[i]; e != null; e = e.next) { - s.writeObject(e.key); - s.writeObject(e.value); - } - } - } finally { - seg.unlock(); - } - } - s.writeObject(null); - s.writeObject(null); - } - - /** - * Reconstitute the <tt>ConcurrentHashMap</tt> instance from a - * stream (i.e., deserialize it). - * @param s the stream - */ - private void readObject(java.io.ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject(); - - // Initialize each segment to be minimally sized, and let grow. - for (int i = 0; i < segments.length; ++i) { - segments[i].setTable(new HashEntry[1]); - } - - // Read the keys and values, and put the mappings in the table - for (;;) { - K key = (K) s.readObject(); - V value = (V) s.readObject(); - if (key == null) - break; - put(key, value); - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentLinkedQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentLinkedQueue.java deleted file mode 100644 index 000f4a4..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentLinkedQueue.java +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; -import java.util.concurrent.atomic.*; - - -/** - * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes. - * This queue orders elements FIFO (first-in-first-out). - * The <em>head</em> of the queue is that element that has been on the - * queue the longest time. - * The <em>tail</em> of the queue is that element that has been on the - * queue the shortest time. New elements - * are inserted at the tail of the queue, and the queue retrieval - * operations obtain elements at the head of the queue. - * A <tt>ConcurrentLinkedQueue</tt> is an appropriate choice when - * many threads will share access to a common collection. - * This queue does not permit <tt>null</tt> elements. - * - * <p>This implementation employs an efficient "wait-free" - * algorithm based on one described in <a - * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple, - * Fast, and Practical Non-Blocking and Blocking Concurrent Queue - * Algorithms</a> by Maged M. Michael and Michael L. Scott. - * - * <p>Beware that, unlike in most collections, the <tt>size</tt> method - * is <em>NOT</em> a constant-time operation. Because of the - * asynchronous nature of these queues, determining the current number - * of elements requires a traversal of the elements. - * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. - * - * <p>Memory consistency effects: As with other concurrent - * collections, actions in a thread prior to placing an object into a - * {@code ConcurrentLinkedQueue} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * actions subsequent to the access or removal of that element from - * the {@code ConcurrentLinkedQueue} in another thread. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - * - */ -public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> - implements Queue<E>, java.io.Serializable { - private static final long serialVersionUID = 196745693267521676L; - - /* - * This is a straight adaptation of Michael & Scott algorithm. - * For explanation, read the paper. The only (minor) algorithmic - * difference is that this version supports lazy deletion of - * internal nodes (method remove(Object)) -- remove CAS'es item - * fields to null. The normal queue operations unlink but then - * pass over nodes with null item fields. Similarly, iteration - * methods ignore those with nulls. - * - * Also note that like most non-blocking algorithms in this - * package, this implementation relies on the fact that in garbage - * collected systems, there is no possibility of ABA problems due - * to recycled nodes, so there is no need to use "counted - * pointers" or related techniques seen in versions used in - * non-GC'ed settings. - */ - - private static class Node<E> { - private volatile E item; - private volatile Node<E> next; - - private static final - AtomicReferenceFieldUpdater<Node, Node> - nextUpdater = - AtomicReferenceFieldUpdater.newUpdater - (Node.class, Node.class, "next"); - private static final - AtomicReferenceFieldUpdater<Node, Object> - itemUpdater = - AtomicReferenceFieldUpdater.newUpdater - (Node.class, Object.class, "item"); - - Node(E x) { item = x; } - - Node(E x, Node<E> n) { item = x; next = n; } - - E getItem() { - return item; - } - - boolean casItem(E cmp, E val) { - return itemUpdater.compareAndSet(this, cmp, val); - } - - void setItem(E val) { - itemUpdater.set(this, val); - } - - Node<E> getNext() { - return next; - } - - boolean casNext(Node<E> cmp, Node<E> val) { - return nextUpdater.compareAndSet(this, cmp, val); - } - - void setNext(Node<E> val) { - nextUpdater.set(this, val); - } - - } - - private static final - AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node> - tailUpdater = - AtomicReferenceFieldUpdater.newUpdater - (ConcurrentLinkedQueue.class, Node.class, "tail"); - private static final - AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node> - headUpdater = - AtomicReferenceFieldUpdater.newUpdater - (ConcurrentLinkedQueue.class, Node.class, "head"); - - private boolean casTail(Node<E> cmp, Node<E> val) { - return tailUpdater.compareAndSet(this, cmp, val); - } - - private boolean casHead(Node<E> cmp, Node<E> val) { - return headUpdater.compareAndSet(this, cmp, val); - } - - - /** - * Pointer to header node, initialized to a dummy node. The first - * actual node is at head.getNext(). - */ - private transient volatile Node<E> head = new Node<E>(null, null); - - /** Pointer to last node on list **/ - private transient volatile Node<E> tail = head; - - - /** - * Creates a <tt>ConcurrentLinkedQueue</tt> that is initially empty. - */ - public ConcurrentLinkedQueue() {} - - /** - * Creates a <tt>ConcurrentLinkedQueue</tt> - * initially containing the elements of the given collection, - * added in traversal order of the collection's iterator. - * @param c the collection of elements to initially contain - * @throws NullPointerException if the specified collection or any - * of its elements are null - */ - public ConcurrentLinkedQueue(Collection<? extends E> c) { - for (Iterator<? extends E> it = c.iterator(); it.hasNext();) - add(it.next()); - } - - // Have to override just to update the javadoc - - /** - * Inserts the specified element at the tail of this queue. - * - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws NullPointerException if the specified element is null - */ - public boolean add(E e) { - return offer(e); - } - - /** - * Inserts the specified element at the tail of this queue. - * - * @return <tt>true</tt> (as specified by {@link Queue#offer}) - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e) { - if (e == null) throw new NullPointerException(); - Node<E> n = new Node<E>(e, null); - for (;;) { - Node<E> t = tail; - Node<E> s = t.getNext(); - if (t == tail) { - if (s == null) { - if (t.casNext(s, n)) { - casTail(t, n); - return true; - } - } else { - casTail(t, s); - } - } - } - } - - public E poll() { - for (;;) { - Node<E> h = head; - Node<E> t = tail; - Node<E> first = h.getNext(); - if (h == head) { - if (h == t) { - if (first == null) - return null; - else - casTail(t, first); - } else if (casHead(h, first)) { - E item = first.getItem(); - if (item != null) { - first.setItem(null); - return item; - } - // else skip over deleted item, continue loop, - } - } - } - } - - public E peek() { // same as poll except don't remove item - for (;;) { - Node<E> h = head; - Node<E> t = tail; - Node<E> first = h.getNext(); - if (h == head) { - if (h == t) { - if (first == null) - return null; - else - casTail(t, first); - } else { - E item = first.getItem(); - if (item != null) - return item; - else // remove deleted node and continue - casHead(h, first); - } - } - } - } - - /** - * Returns the first actual (non-header) node on list. This is yet - * another variant of poll/peek; here returning out the first - * node, not element (so we cannot collapse with peek() without - * introducing race.) - */ - Node<E> first() { - for (;;) { - Node<E> h = head; - Node<E> t = tail; - Node<E> first = h.getNext(); - if (h == head) { - if (h == t) { - if (first == null) - return null; - else - casTail(t, first); - } else { - if (first.getItem() != null) - return first; - else // remove deleted node and continue - casHead(h, first); - } - } - } - } - - - /** - * Returns <tt>true</tt> if this queue contains no elements. - * - * @return <tt>true</tt> if this queue contains no elements - */ - public boolean isEmpty() { - return first() == null; - } - - /** - * Returns the number of elements in this queue. If this queue - * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns - * <tt>Integer.MAX_VALUE</tt>. - * - * <p>Beware that, unlike in most collections, this method is - * <em>NOT</em> a constant-time operation. Because of the - * asynchronous nature of these queues, determining the current - * number of elements requires an O(n) traversal. - * - * @return the number of elements in this queue - */ - public int size() { - int count = 0; - for (Node<E> p = first(); p != null; p = p.getNext()) { - if (p.getItem() != null) { - // Collections.size() spec says to max out - if (++count == Integer.MAX_VALUE) - break; - } - } - return count; - } - - /** - * Returns <tt>true</tt> if this queue contains the specified element. - * More formally, returns <tt>true</tt> if and only if this queue contains - * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. - * - * @param o object to be checked for containment in this queue - * @return <tt>true</tt> if this queue contains the specified element - */ - public boolean contains(Object o) { - if (o == null) return false; - for (Node<E> p = first(); p != null; p = p.getNext()) { - E item = p.getItem(); - if (item != null && - o.equals(item)) - return true; - } - return false; - } - - /** - * Removes a single instance of the specified element from this queue, - * if it is present. More formally, removes an element <tt>e</tt> such - * that <tt>o.equals(e)</tt>, if this queue contains one or more such - * elements. - * Returns <tt>true</tt> if this queue contained the specified element - * (or equivalently, if this queue changed as a result of the call). - * - * @param o element to be removed from this queue, if present - * @return <tt>true</tt> if this queue changed as a result of the call - */ - public boolean remove(Object o) { - if (o == null) return false; - for (Node<E> p = first(); p != null; p = p.getNext()) { - E item = p.getItem(); - if (item != null && - o.equals(item) && - p.casItem(item, null)) - return true; - } - return false; - } - - /** - * 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 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. - * - * @return an iterator over the elements in this queue in proper sequence - */ - public Iterator<E> iterator() { - return new Itr(); - } - - private class Itr implements Iterator<E> { - /** - * Next node to return item for. - */ - private Node<E> nextNode; - - /** - * nextItem holds on to item fields because once we claim - * that an element exists in hasNext(), we must return it in - * the following next() call even if it was in the process of - * being removed when hasNext() was called. - */ - private E nextItem; - - /** - * Node of the last returned item, to support remove. - */ - private Node<E> lastRet; - - Itr() { - advance(); - } - - /** - * Moves to next valid node and returns item to return for - * next(), or null if no such. - */ - private E advance() { - lastRet = nextNode; - E x = nextItem; - - Node<E> p = (nextNode == null)? first() : nextNode.getNext(); - for (;;) { - if (p == null) { - nextNode = null; - nextItem = null; - return x; - } - E item = p.getItem(); - if (item != null) { - nextNode = p; - nextItem = item; - return x; - } else // skip over nulls - p = p.getNext(); - } - } - - public boolean hasNext() { - return nextNode != null; - } - - public E next() { - if (nextNode == null) throw new NoSuchElementException(); - return advance(); - } - - public void remove() { - Node<E> l = lastRet; - if (l == null) throw new IllegalStateException(); - // rely on a future traversal to relink. - l.setItem(null); - lastRet = null; - } - } - - /** - * Save the state to a stream (that is, serialize it). - * - * @serialData All of the elements (each an <tt>E</tt>) in - * the proper order, followed by a null - * @param s the stream - */ - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - - // Write out any hidden stuff - s.defaultWriteObject(); - - // Write out all elements in the proper order. - for (Node<E> p = first(); p != null; p = p.getNext()) { - Object item = p.getItem(); - if (item != null) - s.writeObject(item); - } - - // Use trailing null as sentinel - s.writeObject(null); - } - - /** - * Reconstitute the Queue instance from a stream (that is, - * deserialize it). - * @param s the stream - */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - // Read in capacity, and any hidden stuff - s.defaultReadObject(); - head = new Node<E>(null, null); - tail = head; - // Read in all elements and place in queue - for (;;) { - E item = (E)s.readObject(); - if (item == null) - break; - else - offer(item); - } - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentMap.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentMap.java deleted file mode 100644 index 6e5bd07..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentMap.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.Map; - -/** - * A {@link java.util.Map} providing additional atomic - * <tt>putIfAbsent</tt>, <tt>remove</tt>, and <tt>replace</tt> methods. - * - * <p>Memory consistency effects: As with other concurrent - * collections, actions in a thread prior to placing an object into a - * {@code ConcurrentMap} as a key or value - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * actions subsequent to the access or removal of that object from - * the {@code ConcurrentMap} in another thread. - * - * <p>This interface is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <K> the type of keys maintained by this map - * @param <V> the type of mapped values - */ -public interface ConcurrentMap<K, V> extends Map<K, V> { - /** - * If the specified key is not already associated - * with a value, associate it with the given value. - * This is equivalent to - * <pre> - * if (!map.containsKey(key)) - * return map.put(key, value); - * else - * return map.get(key);</pre> - * except that the action is performed atomically. - * - * @param key key with which the specified value is to be associated - * @param value value to be associated with the specified key - * @return the previous value associated with the specified key, or - * <tt>null</tt> if there was no mapping for the key. - * (A <tt>null</tt> return can also indicate that the map - * previously associated <tt>null</tt> with the key, - * if the implementation supports null values.) - * @throws UnsupportedOperationException if the <tt>put</tt> operation - * is not supported by this map - * @throws ClassCastException if the class of the specified key or value - * prevents it from being stored in this map - * @throws NullPointerException if the specified key or value is null, - * and this map does not permit null keys or values - * @throws IllegalArgumentException if some property of the specified key - * or value prevents it from being stored in this map - * - */ - V putIfAbsent(K key, V value); - - /** - * Removes the entry for a key only if currently mapped to a given value. - * This is equivalent to - * <pre> - * if (map.containsKey(key) && map.get(key).equals(value)) { - * map.remove(key); - * return true; - * } else return false;</pre> - * except that the action is performed atomically. - * - * @param key key with which the specified value is associated - * @param value value expected to be associated with the specified key - * @return <tt>true</tt> if the value was removed - * @throws UnsupportedOperationException if the <tt>remove</tt> operation - * is not supported by this map - * @throws ClassCastException if the key or value is of an inappropriate - * type for this map (optional) - * @throws NullPointerException if the specified key or value is null, - * and this map does not permit null keys or values (optional) - */ - boolean remove(Object key, Object value); - - /** - * Replaces the entry for a key only if currently mapped to a given value. - * This is equivalent to - * <pre> - * if (map.containsKey(key) && map.get(key).equals(oldValue)) { - * map.put(key, newValue); - * return true; - * } else return false;</pre> - * except that the action is performed atomically. - * - * @param key key with which the specified value is associated - * @param oldValue value expected to be associated with the specified key - * @param newValue value to be associated with the specified key - * @return <tt>true</tt> if the value was replaced - * @throws UnsupportedOperationException if the <tt>put</tt> operation - * is not supported by this map - * @throws ClassCastException if the class of a specified key or value - * prevents it from being stored in this map - * @throws NullPointerException if a specified key or value is null, - * and this map does not permit null keys or values - * @throws IllegalArgumentException if some property of a specified key - * or value prevents it from being stored in this map - */ - boolean replace(K key, V oldValue, V newValue); - - /** - * Replaces the entry for a key only if currently mapped to some value. - * This is equivalent to - * <pre> - * if (map.containsKey(key)) { - * return map.put(key, value); - * } else return null;</pre> - * except that the action is performed atomically. - * - * @param key key with which the specified value is associated - * @param value value to be associated with the specified key - * @return the previous value associated with the specified key, or - * <tt>null</tt> if there was no mapping for the key. - * (A <tt>null</tt> return can also indicate that the map - * previously associated <tt>null</tt> with the key, - * if the implementation supports null values.) - * @throws UnsupportedOperationException if the <tt>put</tt> operation - * is not supported by this map - * @throws ClassCastException if the class of the specified key or value - * prevents it from being stored in this map - * @throws NullPointerException if the specified key or value is null, - * and this map does not permit null keys or values - * @throws IllegalArgumentException if some property of the specified key - * or value prevents it from being stored in this map - */ - V replace(K key, V value); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentNavigableMap.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentNavigableMap.java deleted file mode 100644 index 7d86afb..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentNavigableMap.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; - -/** - * A {@link ConcurrentMap} supporting {@link NavigableMap} operations, - * and recursively so for its navigable sub-maps. - * - * <p>This interface is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @author Doug Lea - * @param <K> the type of keys maintained by this map - * @param <V> the type of mapped values - * @since 1.6 - */ -public interface ConcurrentNavigableMap<K,V> - extends ConcurrentMap<K,V>, NavigableMap<K,V> -{ - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, - K toKey, boolean toInclusive); - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive); - - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive); - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey); - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - ConcurrentNavigableMap<K,V> headMap(K toKey); - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - ConcurrentNavigableMap<K,V> tailMap(K fromKey); - - /** - * Returns a reverse order view of the mappings contained in this map. - * The descending map is backed by this map, so changes to the map are - * reflected in the descending map, and vice-versa. - * - * <p>The returned map has an ordering equivalent to - * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. - * The expression {@code m.descendingMap().descendingMap()} returns a - * view of {@code m} essentially equivalent to {@code m}. - * - * @return a reverse order view of this map - */ - ConcurrentNavigableMap<K,V> descendingMap(); - - /** - * Returns a {@link NavigableSet} view of the keys contained in this map. - * The set's iterator returns the keys in ascending order. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from the map, - * via the {@code Iterator.remove}, {@code Set.remove}, - * {@code removeAll}, {@code retainAll}, and {@code clear} - * operations. It does not support the {@code add} or {@code addAll} - * operations. - * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link 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. - * - * @return a navigable set view of the keys in this map - */ - public NavigableSet<K> navigableKeySet(); - - /** - * Returns a {@link NavigableSet} view of the keys contained in this map. - * The set's iterator returns the keys in ascending order. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from the map, - * via the {@code Iterator.remove}, {@code Set.remove}, - * {@code removeAll}, {@code retainAll}, and {@code clear} - * operations. It does not support the {@code add} or {@code addAll} - * operations. - * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link 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. - * - * <p>This method is equivalent to method {@code navigableKeySet}. - * - * @return a navigable set view of the keys in this map - */ - NavigableSet<K> keySet(); - - /** - * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. - * The set's iterator returns the keys in descending order. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from the map, - * via the {@code Iterator.remove}, {@code Set.remove}, - * {@code removeAll}, {@code retainAll}, and {@code clear} - * operations. It does not support the {@code add} or {@code addAll} - * operations. - * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link 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. - * - * @return a reverse order navigable set view of the keys in this map - */ - public NavigableSet<K> descendingKeySet(); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListMap.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListMap.java deleted file mode 100644 index 1ad9244..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListMap.java +++ /dev/null @@ -1,3114 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; -import java.util.concurrent.atomic.*; - -/** - * A scalable concurrent {@link ConcurrentNavigableMap} implementation. - * The map is sorted according to the {@linkplain Comparable natural - * ordering} of its keys, or by a {@link Comparator} provided at map - * creation time, depending on which constructor is used. - * - * <p>This class implements a concurrent variant of <a - * href="http://www.cs.umd.edu/~pugh/">SkipLists</a> providing - * expected average <i>log(n)</i> time cost for the - * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and - * <tt>remove</tt> operations and their variants. Insertion, removal, - * update, and access operations safely execute concurrently by - * multiple threads. Iterators are <i>weakly consistent</i>, returning - * elements reflecting the state of the map at some point at or since - * the creation of the iterator. They do <em>not</em> throw {@link - * ConcurrentModificationException}, and may proceed concurrently with - * other operations. Ascending key ordered views and their iterators - * are faster than descending ones. - * - * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class - * and its views represent snapshots of mappings at the time they were - * produced. They do <em>not</em> support the <tt>Entry.setValue</tt> - * method. (Note however that it is possible to change mappings in the - * associated map using <tt>put</tt>, <tt>putIfAbsent</tt>, or - * <tt>replace</tt>, depending on exactly which effect you need.) - * - * <p>Beware that, unlike in most collections, the <tt>size</tt> - * method is <em>not</em> a constant-time operation. Because of the - * asynchronous nature of these maps, determining the current number - * of elements requires a traversal of the elements. Additionally, - * the bulk operations <tt>putAll</tt>, <tt>equals</tt>, and - * <tt>clear</tt> are <em>not</em> guaranteed to be performed - * atomically. For example, an iterator operating concurrently with a - * <tt>putAll</tt> operation might view only some of the added - * elements. - * - * <p>This class and its views and iterators implement all of the - * <em>optional</em> methods of the {@link Map} and {@link Iterator} - * interfaces. Like most other concurrent collections, this class does - * <em>not</em> permit the use of <tt>null</tt> keys or values because some - * null return values cannot be reliably distinguished from the absence of - * elements. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @author Doug Lea - * @param <K> the type of keys maintained by this map - * @param <V> the type of mapped values - * @since 1.6 - */ -public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> - implements ConcurrentNavigableMap<K,V>, - Cloneable, - java.io.Serializable { - /* - * This class implements a tree-like two-dimensionally linked skip - * list in which the index levels are represented in separate - * nodes from the base nodes holding data. There are two reasons - * for taking this approach instead of the usual array-based - * structure: 1) Array based implementations seem to encounter - * more complexity and overhead 2) We can use cheaper algorithms - * for the heavily-traversed index lists than can be used for the - * base lists. Here's a picture of some of the basics for a - * possible list with 2 levels of index: - * - * Head nodes Index nodes - * +-+ right +-+ +-+ - * |2|---------------->| |--------------------->| |->null - * +-+ +-+ +-+ - * | down | | - * v v v - * +-+ +-+ +-+ +-+ +-+ +-+ - * |1|----------->| |->| |------>| |----------->| |------>| |->null - * +-+ +-+ +-+ +-+ +-+ +-+ - * v | | | | | - * Nodes next v v v v v - * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ - * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null - * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ - * - * The base lists use a variant of the HM linked ordered set - * algorithm. See Tim Harris, "A pragmatic implementation of - * non-blocking linked lists" - * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged - * Michael "High Performance Dynamic Lock-Free Hash Tables and - * List-Based Sets" - * http://www.research.ibm.com/people/m/michael/pubs.htm. The - * basic idea in these lists is to mark the "next" pointers of - * deleted nodes when deleting to avoid conflicts with concurrent - * insertions, and when traversing to keep track of triples - * (predecessor, node, successor) in order to detect when and how - * to unlink these deleted nodes. - * - * Rather than using mark-bits to mark list deletions (which can - * be slow and space-intensive using AtomicMarkedReference), nodes - * use direct CAS'able next pointers. On deletion, instead of - * marking a pointer, they splice in another node that can be - * thought of as standing for a marked pointer (indicating this by - * using otherwise impossible field values). Using plain nodes - * acts roughly like "boxed" implementations of marked pointers, - * but uses new nodes only when nodes are deleted, not for every - * link. This requires less space and supports faster - * traversal. Even if marked references were better supported by - * JVMs, traversal using this technique might still be faster - * because any search need only read ahead one more node than - * otherwise required (to check for trailing marker) rather than - * unmasking mark bits or whatever on each read. - * - * This approach maintains the essential property needed in the HM - * algorithm of changing the next-pointer of a deleted node so - * that any other CAS of it will fail, but implements the idea by - * changing the pointer to point to a different node, not by - * marking it. While it would be possible to further squeeze - * space by defining marker nodes not to have key/value fields, it - * isn't worth the extra type-testing overhead. The deletion - * markers are rarely encountered during traversal and are - * normally quickly garbage collected. (Note that this technique - * would not work well in systems without garbage collection.) - * - * In addition to using deletion markers, the lists also use - * nullness of value fields to indicate deletion, in a style - * similar to typical lazy-deletion schemes. If a node's value is - * null, then it is considered logically deleted and ignored even - * though it is still reachable. This maintains proper control of - * concurrent replace vs delete operations -- an attempted replace - * must fail if a delete beat it by nulling field, and a delete - * must return the last non-null value held in the field. (Note: - * Null, rather than some special marker, is used for value fields - * here because it just so happens to mesh with the Map API - * requirement that method get returns null if there is no - * mapping, which allows nodes to remain concurrently readable - * even when deleted. Using any other marker value here would be - * messy at best.) - * - * Here's the sequence of events for a deletion of node n with - * predecessor b and successor f, initially: - * - * +------+ +------+ +------+ - * ... | b |------>| n |----->| f | ... - * +------+ +------+ +------+ - * - * 1. CAS n's value field from non-null to null. - * From this point on, no public operations encountering - * the node consider this mapping to exist. However, other - * ongoing insertions and deletions might still modify - * n's next pointer. - * - * 2. CAS n's next pointer to point to a new marker node. - * From this point on, no other nodes can be appended to n. - * which avoids deletion errors in CAS-based linked lists. - * - * +------+ +------+ +------+ +------+ - * ... | b |------>| n |----->|marker|------>| f | ... - * +------+ +------+ +------+ +------+ - * - * 3. CAS b's next pointer over both n and its marker. - * From this point on, no new traversals will encounter n, - * and it can eventually be GCed. - * +------+ +------+ - * ... | b |----------------------------------->| f | ... - * +------+ +------+ - * - * A failure at step 1 leads to simple retry due to a lost race - * with another operation. Steps 2-3 can fail because some other - * thread noticed during a traversal a node with null value and - * helped out by marking and/or unlinking. This helping-out - * ensures that no thread can become stuck waiting for progress of - * the deleting thread. The use of marker nodes slightly - * complicates helping-out code because traversals must track - * consistent reads of up to four nodes (b, n, marker, f), not - * just (b, n, f), although the next field of a marker is - * immutable, and once a next field is CAS'ed to point to a - * marker, it never again changes, so this requires less care. - * - * Skip lists add indexing to this scheme, so that the base-level - * traversals start close to the locations being found, inserted - * or deleted -- usually base level traversals only traverse a few - * nodes. This doesn't change the basic algorithm except for the - * need to make sure base traversals start at predecessors (here, - * b) that are not (structurally) deleted, otherwise retrying - * after processing the deletion. - * - * Index levels are maintained as lists with volatile next fields, - * using CAS to link and unlink. Races are allowed in index-list - * operations that can (rarely) fail to link in a new index node - * or delete one. (We can't do this of course for data nodes.) - * However, even when this happens, the index lists remain sorted, - * so correctly serve as indices. This can impact performance, - * but since skip lists are probabilistic anyway, the net result - * is that under contention, the effective "p" value may be lower - * than its nominal value. And race windows are kept small enough - * that in practice these failures are rare, even under a lot of - * contention. - * - * The fact that retries (for both base and index lists) are - * relatively cheap due to indexing allows some minor - * simplifications of retry logic. Traversal restarts are - * performed after most "helping-out" CASes. This isn't always - * strictly necessary, but the implicit backoffs tend to help - * reduce other downstream failed CAS's enough to outweigh restart - * cost. This worsens the worst case, but seems to improve even - * highly contended cases. - * - * Unlike most skip-list implementations, index insertion and - * deletion here require a separate traversal pass occuring after - * the base-level action, to add or remove index nodes. This adds - * to single-threaded overhead, but improves contended - * multithreaded performance by narrowing interference windows, - * and allows deletion to ensure that all index nodes will be made - * unreachable upon return from a public remove operation, thus - * avoiding unwanted garbage retention. This is more important - * here than in some other data structures because we cannot null - * out node fields referencing user keys since they might still be - * read by other ongoing traversals. - * - * Indexing uses skip list parameters that maintain good search - * performance while using sparser-than-usual indices: The - * hardwired parameters k=1, p=0.5 (see method randomLevel) mean - * that about one-quarter of the nodes have indices. Of those that - * do, half have one level, a quarter have two, and so on (see - * Pugh's Skip List Cookbook, sec 3.4). The expected total space - * requirement for a map is slightly less than for the current - * implementation of java.util.TreeMap. - * - * Changing the level of the index (i.e, the height of the - * tree-like structure) also uses CAS. The head index has initial - * level/height of one. Creation of an index with height greater - * than the current level adds a level to the head index by - * CAS'ing on a new top-most head. To maintain good performance - * after a lot of removals, deletion methods heuristically try to - * reduce the height if the topmost levels appear to be empty. - * This may encounter races in which it possible (but rare) to - * reduce and "lose" a level just as it is about to contain an - * index (that will then never be encountered). This does no - * structural harm, and in practice appears to be a better option - * than allowing unrestrained growth of levels. - * - * The code for all this is more verbose than you'd like. Most - * operations entail locating an element (or position to insert an - * element). The code to do this can't be nicely factored out - * because subsequent uses require a snapshot of predecessor - * and/or successor and/or value fields which can't be returned - * all at once, at least not without creating yet another object - * to hold them -- creating such little objects is an especially - * bad idea for basic internal search operations because it adds - * to GC overhead. (This is one of the few times I've wished Java - * had macros.) Instead, some traversal code is interleaved within - * insertion and removal operations. The control logic to handle - * all the retry conditions is sometimes twisty. Most search is - * broken into 2 parts. findPredecessor() searches index nodes - * only, returning a base-level predecessor of the key. findNode() - * finishes out the base-level search. Even with this factoring, - * there is a fair amount of near-duplication of code to handle - * variants. - * - * For explanation of algorithms sharing at least a couple of - * features with this one, see Mikhail Fomitchev's thesis - * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis - * (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell's - * thesis (http://www.cs.chalmers.se/~phs/). - * - * Given the use of tree-like index nodes, you might wonder why - * this doesn't use some kind of search tree instead, which would - * support somewhat faster search operations. The reason is that - * there are no known efficient lock-free insertion and deletion - * algorithms for search trees. The immutability of the "down" - * links of index nodes (as opposed to mutable "left" fields in - * true trees) makes this tractable using only CAS operations. - * - * Notation guide for local variables - * Node: b, n, f for predecessor, node, successor - * Index: q, r, d for index node, right, down. - * t for another index node - * Head: h - * Levels: j - * Keys: k, key - * Values: v, value - * Comparisons: c - */ - - private static final long serialVersionUID = -8627078645895051609L; - - /** - * Generates the initial random seed for the cheaper per-instance - * random number generators used in randomLevel. - */ - private static final Random seedGenerator = new Random(); - - /** - * Special value used to identify base-level header - */ - private static final Object BASE_HEADER = new Object(); - - /** - * The topmost head index of the skiplist. - */ - private transient volatile HeadIndex<K,V> head; - - /** - * The comparator used to maintain order in this map, or null - * if using natural ordering. - * @serial - */ - private final Comparator<? super K> comparator; - - /** - * Seed for simple random number generator. Not volatile since it - * doesn't matter too much if different threads don't see updates. - */ - private transient int randomSeed; - - /** Lazily initialized key set */ - private transient KeySet keySet; - /** Lazily initialized entry set */ - private transient EntrySet entrySet; - /** Lazily initialized values collection */ - private transient Values values; - /** Lazily initialized descending key set */ - private transient ConcurrentNavigableMap<K,V> descendingMap; - - /** - * Initializes or resets state. Needed by constructors, clone, - * clear, readObject. and ConcurrentSkipListSet.clone. - * (Note that comparator must be separately initialized.) - */ - final void initialize() { - keySet = null; - entrySet = null; - values = null; - descendingMap = null; - randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero - head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null), - null, null, 1); - } - - /** Updater for casHead */ - private static final - AtomicReferenceFieldUpdater<ConcurrentSkipListMap, HeadIndex> - headUpdater = AtomicReferenceFieldUpdater.newUpdater - (ConcurrentSkipListMap.class, HeadIndex.class, "head"); - - /** - * compareAndSet head node - */ - private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) { - return headUpdater.compareAndSet(this, cmp, val); - } - - /* ---------------- Nodes -------------- */ - - /** - * Nodes hold keys and values, and are singly linked in sorted - * order, possibly with some intervening marker nodes. The list is - * headed by a dummy node accessible as head.node. The value field - * is declared only as Object because it takes special non-V - * values for marker and header nodes. - */ - static final class Node<K,V> { - final K key; - volatile Object value; - volatile Node<K,V> next; - - /** - * Creates a new regular node. - */ - Node(K key, Object value, Node<K,V> next) { - this.key = key; - this.value = value; - this.next = next; - } - - /** - * Creates a new marker node. A marker is distinguished by - * having its value field point to itself. Marker nodes also - * have null keys, a fact that is exploited in a few places, - * but this doesn't distinguish markers from the base-level - * header node (head.node), which also has a null key. - */ - Node(Node<K,V> next) { - this.key = null; - this.value = this; - this.next = next; - } - - /** Updater for casNext */ - static final AtomicReferenceFieldUpdater<Node, Node> - nextUpdater = AtomicReferenceFieldUpdater.newUpdater - (Node.class, Node.class, "next"); - - /** Updater for casValue */ - static final AtomicReferenceFieldUpdater<Node, Object> - valueUpdater = AtomicReferenceFieldUpdater.newUpdater - (Node.class, Object.class, "value"); - - /** - * compareAndSet value field - */ - boolean casValue(Object cmp, Object val) { - return valueUpdater.compareAndSet(this, cmp, val); - } - - /** - * compareAndSet next field - */ - boolean casNext(Node<K,V> cmp, Node<K,V> val) { - return nextUpdater.compareAndSet(this, cmp, val); - } - - /** - * Returns true if this node is a marker. This method isn't - * actually called in any current code checking for markers - * because callers will have already read value field and need - * to use that read (not another done here) and so directly - * test if value points to node. - * @param n a possibly null reference to a node - * @return true if this node is a marker node - */ - boolean isMarker() { - return value == this; - } - - /** - * Returns true if this node is the header of base-level list. - * @return true if this node is header node - */ - boolean isBaseHeader() { - return value == BASE_HEADER; - } - - /** - * Tries to append a deletion marker to this node. - * @param f the assumed current successor of this node - * @return true if successful - */ - boolean appendMarker(Node<K,V> f) { - return casNext(f, new Node<K,V>(f)); - } - - /** - * Helps out a deletion by appending marker or unlinking from - * predecessor. This is called during traversals when value - * field seen to be null. - * @param b predecessor - * @param f successor - */ - void helpDelete(Node<K,V> b, Node<K,V> f) { - /* - * Rechecking links and then doing only one of the - * help-out stages per call tends to minimize CAS - * interference among helping threads. - */ - if (f == next && this == b.next) { - if (f == null || f.value != f) // not already marked - appendMarker(f); - else - b.casNext(this, f.next); - } - } - - /** - * Returns value if this node contains a valid key-value pair, - * else null. - * @return this node's value if it isn't a marker or header or - * is deleted, else null. - */ - V getValidValue() { - Object v = value; - if (v == this || v == BASE_HEADER) - return null; - return (V)v; - } - - /** - * Creates and returns a new SimpleImmutableEntry holding current - * mapping if this node holds a valid value, else null. - * @return new entry or null - */ - AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() { - V v = getValidValue(); - if (v == null) - return null; - return new AbstractMap.SimpleImmutableEntry<K,V>(key, v); - } - } - - /* ---------------- Indexing -------------- */ - - /** - * Index nodes represent the levels of the skip list. Note that - * even though both Nodes and Indexes have forward-pointing - * fields, they have different types and are handled in different - * ways, that can't nicely be captured by placing field in a - * shared abstract class. - */ - static class Index<K,V> { - final Node<K,V> node; - final Index<K,V> down; - volatile Index<K,V> right; - - /** - * Creates index node with given values. - */ - Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) { - this.node = node; - this.down = down; - this.right = right; - } - - /** Updater for casRight */ - static final AtomicReferenceFieldUpdater<Index, Index> - rightUpdater = AtomicReferenceFieldUpdater.newUpdater - (Index.class, Index.class, "right"); - - /** - * compareAndSet right field - */ - final boolean casRight(Index<K,V> cmp, Index<K,V> val) { - return rightUpdater.compareAndSet(this, cmp, val); - } - - /** - * Returns true if the node this indexes has been deleted. - * @return true if indexed node is known to be deleted - */ - final boolean indexesDeletedNode() { - return node.value == null; - } - - /** - * Tries to CAS newSucc as successor. To minimize races with - * unlink that may lose this index node, if the node being - * indexed is known to be deleted, it doesn't try to link in. - * @param succ the expected current successor - * @param newSucc the new successor - * @return true if successful - */ - final boolean link(Index<K,V> succ, Index<K,V> newSucc) { - Node<K,V> n = node; - newSucc.right = succ; - return n.value != null && casRight(succ, newSucc); - } - - /** - * Tries to CAS right field to skip over apparent successor - * succ. Fails (forcing a retraversal by caller) if this node - * is known to be deleted. - * @param succ the expected current successor - * @return true if successful - */ - final boolean unlink(Index<K,V> succ) { - return !indexesDeletedNode() && casRight(succ, succ.right); - } - } - - /* ---------------- Head nodes -------------- */ - - /** - * Nodes heading each level keep track of their level. - */ - static final class HeadIndex<K,V> extends Index<K,V> { - final int level; - HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) { - super(node, down, right); - this.level = level; - } - } - - /* ---------------- Comparison utilities -------------- */ - - /** - * Represents a key with a comparator as a Comparable. - * - * Because most sorted collections seem to use natural ordering on - * Comparables (Strings, Integers, etc), most internal methods are - * geared to use them. This is generally faster than checking - * per-comparison whether to use comparator or comparable because - * it doesn't require a (Comparable) cast for each comparison. - * (Optimizers can only sometimes remove such redundant checks - * themselves.) When Comparators are used, - * ComparableUsingComparators are created so that they act in the - * same way as natural orderings. This penalizes use of - * Comparators vs Comparables, which seems like the right - * tradeoff. - */ - static final class ComparableUsingComparator<K> implements Comparable<K> { - final K actualKey; - final Comparator<? super K> cmp; - ComparableUsingComparator(K key, Comparator<? super K> cmp) { - this.actualKey = key; - this.cmp = cmp; - } - public int compareTo(K k2) { - return cmp.compare(actualKey, k2); - } - } - - /** - * If using comparator, return a ComparableUsingComparator, else - * cast key as Comparable, which may cause ClassCastException, - * which is propagated back to caller. - */ - private Comparable<? super K> comparable(Object key) throws ClassCastException { - if (key == null) - throw new NullPointerException(); - if (comparator != null) - return new ComparableUsingComparator<K>((K)key, comparator); - else - return (Comparable<? super K>)key; - } - - /** - * Compares using comparator or natural ordering. Used when the - * ComparableUsingComparator approach doesn't apply. - */ - int compare(K k1, K k2) throws ClassCastException { - Comparator<? super K> cmp = comparator; - if (cmp != null) - return cmp.compare(k1, k2); - else - return ((Comparable<? super K>)k1).compareTo(k2); - } - - /** - * Returns true if given key greater than or equal to least and - * strictly less than fence, bypassing either test if least or - * fence are null. Needed mainly in submap operations. - */ - boolean inHalfOpenRange(K key, K least, K fence) { - if (key == null) - throw new NullPointerException(); - return ((least == null || compare(key, least) >= 0) && - (fence == null || compare(key, fence) < 0)); - } - - /** - * Returns true if given key greater than or equal to least and less - * or equal to fence. Needed mainly in submap operations. - */ - boolean inOpenRange(K key, K least, K fence) { - if (key == null) - throw new NullPointerException(); - return ((least == null || compare(key, least) >= 0) && - (fence == null || compare(key, fence) <= 0)); - } - - /* ---------------- Traversal -------------- */ - - /** - * Returns a base-level node with key strictly less than given key, - * or the base-level header if there is no such node. Also - * unlinks indexes to deleted nodes found along the way. Callers - * rely on this side-effect of clearing indices to deleted nodes. - * @param key the key - * @return a predecessor of key - */ - private Node<K,V> findPredecessor(Comparable<? super K> key) { - if (key == null) - throw new NullPointerException(); // don't postpone errors - for (;;) { - Index<K,V> q = head; - Index<K,V> r = q.right; - for (;;) { - if (r != null) { - Node<K,V> n = r.node; - K k = n.key; - if (n.value == null) { - if (!q.unlink(r)) - break; // restart - r = q.right; // reread r - continue; - } - if (key.compareTo(k) > 0) { - q = r; - r = r.right; - continue; - } - } - Index<K,V> d = q.down; - if (d != null) { - q = d; - r = d.right; - } else - return q.node; - } - } - } - - /** - * Returns node holding key or null if no such, clearing out any - * deleted nodes seen along the way. Repeatedly traverses at - * base-level looking for key starting at predecessor returned - * from findPredecessor, processing base-level deletions as - * encountered. Some callers rely on this side-effect of clearing - * deleted nodes. - * - * Restarts occur, at traversal step centered on node n, if: - * - * (1) After reading n's next field, n is no longer assumed - * predecessor b's current successor, which means that - * we don't have a consistent 3-node snapshot and so cannot - * unlink any subsequent deleted nodes encountered. - * - * (2) n's value field is null, indicating n is deleted, in - * which case we help out an ongoing structural deletion - * before retrying. Even though there are cases where such - * unlinking doesn't require restart, they aren't sorted out - * here because doing so would not usually outweigh cost of - * restarting. - * - * (3) n is a marker or n's predecessor's value field is null, - * indicating (among other possibilities) that - * findPredecessor returned a deleted node. We can't unlink - * the node because we don't know its predecessor, so rely - * on another call to findPredecessor to notice and return - * some earlier predecessor, which it will do. This check is - * only strictly needed at beginning of loop, (and the - * b.value check isn't strictly needed at all) but is done - * each iteration to help avoid contention with other - * threads by callers that will fail to be able to change - * links, and so will retry anyway. - * - * The traversal loops in doPut, doRemove, and findNear all - * include the same three kinds of checks. And specialized - * versions appear in findFirst, and findLast and their - * variants. They can't easily share code because each uses the - * reads of fields held in locals occurring in the orders they - * were performed. - * - * @param key the key - * @return node holding key, or null if no such - */ - private Node<K,V> findNode(Comparable<? super K> key) { - for (;;) { - Node<K,V> b = findPredecessor(key); - Node<K,V> n = b.next; - for (;;) { - if (n == null) - return null; - Node<K,V> f = n.next; - if (n != b.next) // inconsistent read - break; - Object v = n.value; - if (v == null) { // n is deleted - n.helpDelete(b, f); - break; - } - if (v == n || b.value == null) // b is deleted - break; - int c = key.compareTo(n.key); - if (c == 0) - return n; - if (c < 0) - return null; - b = n; - n = f; - } - } - } - - /** - * Specialized variant of findNode to perform Map.get. Does a weak - * traversal, not bothering to fix any deleted index nodes, - * returning early if it happens to see key in index, and passing - * over any deleted base nodes, falling back to getUsingFindNode - * only if it would otherwise return value from an ongoing - * deletion. Also uses "bound" to eliminate need for some - * comparisons (see Pugh Cookbook). Also folds uses of null checks - * and node-skipping because markers have null keys. - * @param okey the key - * @return the value, or null if absent - */ - private V doGet(Object okey) { - Comparable<? super K> key = comparable(okey); - Node<K,V> bound = null; - Index<K,V> q = head; - Index<K,V> r = q.right; - Node<K,V> n; - K k; - int c; - for (;;) { - Index<K,V> d; - // Traverse rights - if (r != null && (n = r.node) != bound && (k = n.key) != null) { - if ((c = key.compareTo(k)) > 0) { - q = r; - r = r.right; - continue; - } else if (c == 0) { - Object v = n.value; - return (v != null)? (V)v : getUsingFindNode(key); - } else - bound = n; - } - - // Traverse down - if ((d = q.down) != null) { - q = d; - r = d.right; - } else - break; - } - - // Traverse nexts - for (n = q.node.next; n != null; n = n.next) { - if ((k = n.key) != null) { - if ((c = key.compareTo(k)) == 0) { - Object v = n.value; - return (v != null)? (V)v : getUsingFindNode(key); - } else if (c < 0) - break; - } - } - return null; - } - - /** - * Performs map.get via findNode. Used as a backup if doGet - * encounters an in-progress deletion. - * @param key the key - * @return the value, or null if absent - */ - private V getUsingFindNode(Comparable<? super K> key) { - /* - * Loop needed here and elsewhere in case value field goes - * null just as it is about to be returned, in which case we - * lost a race with a deletion, so must retry. - */ - for (;;) { - Node<K,V> n = findNode(key); - if (n == null) - return null; - Object v = n.value; - if (v != null) - return (V)v; - } - } - - /* ---------------- Insertion -------------- */ - - /** - * Main insertion method. Adds element if not present, or - * replaces value if present and onlyIfAbsent is false. - * @param kkey the key - * @param value the value that must be associated with key - * @param onlyIfAbsent if should not insert if already present - * @return the old value, or null if newly inserted - */ - private V doPut(K kkey, V value, boolean onlyIfAbsent) { - Comparable<? super K> key = comparable(kkey); - for (;;) { - Node<K,V> b = findPredecessor(key); - Node<K,V> n = b.next; - for (;;) { - if (n != null) { - Node<K,V> f = n.next; - if (n != b.next) // inconsistent read - break; - Object v = n.value; - if (v == null) { // n is deleted - n.helpDelete(b, f); - break; - } - if (v == n || b.value == null) // b is deleted - break; - int c = key.compareTo(n.key); - if (c > 0) { - b = n; - n = f; - continue; - } - if (c == 0) { - if (onlyIfAbsent || n.casValue(v, value)) - return (V)v; - else - break; // restart if lost race to replace value - } - // else c < 0; fall through - } - - Node<K,V> z = new Node<K,V>(kkey, value, n); - if (!b.casNext(n, z)) - break; // restart if lost race to append to b - int level = randomLevel(); - if (level > 0) - insertIndex(z, level); - return null; - } - } - } - - /** - * Returns a random level for inserting a new node. - * Hardwired to k=1, p=0.5, max 31 (see above and - * Pugh's "Skip List Cookbook", sec 3.4). - * - * This uses the simplest of the generators described in George - * Marsaglia's "Xorshift RNGs" paper. This is not a high-quality - * generator but is acceptable here. - */ - private int randomLevel() { - int x = randomSeed; - x ^= x << 13; - x ^= x >>> 17; - randomSeed = x ^= x << 5; - if ((x & 0x8001) != 0) // test highest and lowest bits - return 0; - int level = 1; - while (((x >>>= 1) & 1) != 0) ++level; - return level; - } - - /** - * Creates and adds index nodes for the given node. - * @param z the node - * @param level the level of the index - */ - private void insertIndex(Node<K,V> z, int level) { - HeadIndex<K,V> h = head; - int max = h.level; - - if (level <= max) { - Index<K,V> idx = null; - for (int i = 1; i <= level; ++i) - idx = new Index<K,V>(z, idx, null); - addIndex(idx, h, level); - - } else { // Add a new level - /* - * To reduce interference by other threads checking for - * empty levels in tryReduceLevel, new levels are added - * with initialized right pointers. Which in turn requires - * keeping levels in an array to access them while - * creating new head index nodes from the opposite - * direction. - */ - level = max + 1; - Index<K,V>[] idxs = (Index<K,V>[])new Index[level+1]; - Index<K,V> idx = null; - for (int i = 1; i <= level; ++i) - idxs[i] = idx = new Index<K,V>(z, idx, null); - - HeadIndex<K,V> oldh; - int k; - for (;;) { - oldh = head; - int oldLevel = oldh.level; - if (level <= oldLevel) { // lost race to add level - k = level; - break; - } - HeadIndex<K,V> newh = oldh; - Node<K,V> oldbase = oldh.node; - for (int j = oldLevel+1; j <= level; ++j) - newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j); - if (casHead(oldh, newh)) { - k = oldLevel; - break; - } - } - addIndex(idxs[k], oldh, k); - } - } - - /** - * Adds given index nodes from given level down to 1. - * @param idx the topmost index node being inserted - * @param h the value of head to use to insert. This must be - * snapshotted by callers to provide correct insertion level - * @param indexLevel the level of the index - */ - private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) { - // Track next level to insert in case of retries - int insertionLevel = indexLevel; - Comparable<? super K> key = comparable(idx.node.key); - if (key == null) throw new NullPointerException(); - - // Similar to findPredecessor, but adding index nodes along - // path to key. - for (;;) { - int j = h.level; - Index<K,V> q = h; - Index<K,V> r = q.right; - Index<K,V> t = idx; - for (;;) { - if (r != null) { - Node<K,V> n = r.node; - // compare before deletion check avoids needing recheck - int c = key.compareTo(n.key); - if (n.value == null) { - if (!q.unlink(r)) - break; - r = q.right; - continue; - } - if (c > 0) { - q = r; - r = r.right; - continue; - } - } - - if (j == insertionLevel) { - // Don't insert index if node already deleted - if (t.indexesDeletedNode()) { - findNode(key); // cleans up - return; - } - if (!q.link(r, t)) - break; // restart - if (--insertionLevel == 0) { - // need final deletion check before return - if (t.indexesDeletedNode()) - findNode(key); - return; - } - } - - if (--j >= insertionLevel && j < indexLevel) - t = t.down; - q = q.down; - r = q.right; - } - } - } - - /* ---------------- Deletion -------------- */ - - /** - * Main deletion method. Locates node, nulls value, appends a - * deletion marker, unlinks predecessor, removes associated index - * nodes, and possibly reduces head index level. - * - * Index nodes are cleared out simply by calling findPredecessor. - * which unlinks indexes to deleted nodes found along path to key, - * which will include the indexes to this node. This is done - * unconditionally. We can't check beforehand whether there are - * index nodes because it might be the case that some or all - * indexes hadn't been inserted yet for this node during initial - * search for it, and we'd like to ensure lack of garbage - * retention, so must call to be sure. - * - * @param okey the key - * @param value if non-null, the value that must be - * associated with key - * @return the node, or null if not found - */ - final V doRemove(Object okey, Object value) { - Comparable<? super K> key = comparable(okey); - for (;;) { - Node<K,V> b = findPredecessor(key); - Node<K,V> n = b.next; - for (;;) { - if (n == null) - return null; - Node<K,V> f = n.next; - if (n != b.next) // inconsistent read - break; - Object v = n.value; - if (v == null) { // n is deleted - n.helpDelete(b, f); - break; - } - if (v == n || b.value == null) // b is deleted - break; - int c = key.compareTo(n.key); - if (c < 0) - return null; - if (c > 0) { - b = n; - n = f; - continue; - } - if (value != null && !value.equals(v)) - return null; - if (!n.casValue(v, null)) - break; - if (!n.appendMarker(f) || !b.casNext(n, f)) - findNode(key); // Retry via findNode - else { - findPredecessor(key); // Clean index - if (head.right == null) - tryReduceLevel(); - } - return (V)v; - } - } - } - - /** - * Possibly reduce head level if it has no nodes. This method can - * (rarely) make mistakes, in which case levels can disappear even - * though they are about to contain index nodes. This impacts - * performance, not correctness. To minimize mistakes as well as - * to reduce hysteresis, the level is reduced by one only if the - * topmost three levels look empty. Also, if the removed level - * looks non-empty after CAS, we try to change it back quick - * before anyone notices our mistake! (This trick works pretty - * well because this method will practically never make mistakes - * unless current thread stalls immediately before first CAS, in - * which case it is very unlikely to stall again immediately - * afterwards, so will recover.) - * - * We put up with all this rather than just let levels grow - * because otherwise, even a small map that has undergone a large - * number of insertions and removals will have a lot of levels, - * slowing down access more than would an occasional unwanted - * reduction. - */ - private void tryReduceLevel() { - HeadIndex<K,V> h = head; - HeadIndex<K,V> d; - HeadIndex<K,V> e; - if (h.level > 3 && - (d = (HeadIndex<K,V>)h.down) != null && - (e = (HeadIndex<K,V>)d.down) != null && - e.right == null && - d.right == null && - h.right == null && - casHead(h, d) && // try to set - h.right != null) // recheck - casHead(d, h); // try to backout - } - - /* ---------------- Finding and removing first element -------------- */ - - /** - * Specialized variant of findNode to get first valid node. - * @return first node or null if empty - */ - Node<K,V> findFirst() { - for (;;) { - Node<K,V> b = head.node; - Node<K,V> n = b.next; - if (n == null) - return null; - if (n.value != null) - return n; - n.helpDelete(b, n.next); - } - } - - /** - * Removes first entry; returns its snapshot. - * @return null if empty, else snapshot of first entry - */ - Map.Entry<K,V> doRemoveFirstEntry() { - for (;;) { - Node<K,V> b = head.node; - Node<K,V> n = b.next; - if (n == null) - return null; - Node<K,V> f = n.next; - if (n != b.next) - continue; - Object v = n.value; - if (v == null) { - n.helpDelete(b, f); - continue; - } - if (!n.casValue(v, null)) - continue; - if (!n.appendMarker(f) || !b.casNext(n, f)) - findFirst(); // retry - clearIndexToFirst(); - return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v); - } - } - - /** - * Clears out index nodes associated with deleted first entry. - */ - private void clearIndexToFirst() { - for (;;) { - Index<K,V> q = head; - for (;;) { - Index<K,V> r = q.right; - if (r != null && r.indexesDeletedNode() && !q.unlink(r)) - break; - if ((q = q.down) == null) { - if (head.right == null) - tryReduceLevel(); - return; - } - } - } - } - - - /* ---------------- Finding and removing last element -------------- */ - - /** - * Specialized version of find to get last valid node. - * @return last node or null if empty - */ - Node<K,V> findLast() { - /* - * findPredecessor can't be used to traverse index level - * because this doesn't use comparisons. So traversals of - * both levels are folded together. - */ - Index<K,V> q = head; - for (;;) { - Index<K,V> d, r; - if ((r = q.right) != null) { - if (r.indexesDeletedNode()) { - q.unlink(r); - q = head; // restart - } - else - q = r; - } else if ((d = q.down) != null) { - q = d; - } else { - Node<K,V> b = q.node; - Node<K,V> n = b.next; - for (;;) { - if (n == null) - return (b.isBaseHeader())? null : b; - Node<K,V> f = n.next; // inconsistent read - if (n != b.next) - break; - Object v = n.value; - if (v == null) { // n is deleted - n.helpDelete(b, f); - break; - } - if (v == n || b.value == null) // b is deleted - break; - b = n; - n = f; - } - q = head; // restart - } - } - } - - /** - * Specialized variant of findPredecessor to get predecessor of last - * valid node. Needed when removing the last entry. It is possible - * that all successors of returned node will have been deleted upon - * return, in which case this method can be retried. - * @return likely predecessor of last node - */ - private Node<K,V> findPredecessorOfLast() { - for (;;) { - Index<K,V> q = head; - for (;;) { - Index<K,V> d, r; - if ((r = q.right) != null) { - if (r.indexesDeletedNode()) { - q.unlink(r); - break; // must restart - } - // proceed as far across as possible without overshooting - if (r.node.next != null) { - q = r; - continue; - } - } - if ((d = q.down) != null) - q = d; - else - return q.node; - } - } - } - - /** - * Removes last entry; returns its snapshot. - * Specialized variant of doRemove. - * @return null if empty, else snapshot of last entry - */ - Map.Entry<K,V> doRemoveLastEntry() { - for (;;) { - Node<K,V> b = findPredecessorOfLast(); - Node<K,V> n = b.next; - if (n == null) { - if (b.isBaseHeader()) // empty - return null; - else - continue; // all b's successors are deleted; retry - } - for (;;) { - Node<K,V> f = n.next; - if (n != b.next) // inconsistent read - break; - Object v = n.value; - if (v == null) { // n is deleted - n.helpDelete(b, f); - break; - } - if (v == n || b.value == null) // b is deleted - break; - if (f != null) { - b = n; - n = f; - continue; - } - if (!n.casValue(v, null)) - break; - K key = n.key; - Comparable<? super K> ck = comparable(key); - if (!n.appendMarker(f) || !b.casNext(n, f)) - findNode(ck); // Retry via findNode - else { - findPredecessor(ck); // Clean index - if (head.right == null) - tryReduceLevel(); - } - return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v); - } - } - } - - /* ---------------- Relational operations -------------- */ - - // Control values OR'ed as arguments to findNear - - private static final int EQ = 1; - private static final int LT = 2; - private static final int GT = 0; // Actually checked as !LT - - /** - * Utility for ceiling, floor, lower, higher methods. - * @param kkey the key - * @param rel the relation -- OR'ed combination of EQ, LT, GT - * @return nearest node fitting relation, or null if no such - */ - Node<K,V> findNear(K kkey, int rel) { - Comparable<? super K> key = comparable(kkey); - for (;;) { - Node<K,V> b = findPredecessor(key); - Node<K,V> n = b.next; - for (;;) { - if (n == null) - return ((rel & LT) == 0 || b.isBaseHeader())? null : b; - Node<K,V> f = n.next; - if (n != b.next) // inconsistent read - break; - Object v = n.value; - if (v == null) { // n is deleted - n.helpDelete(b, f); - break; - } - if (v == n || b.value == null) // b is deleted - break; - int c = key.compareTo(n.key); - if ((c == 0 && (rel & EQ) != 0) || - (c < 0 && (rel & LT) == 0)) - return n; - if ( c <= 0 && (rel & LT) != 0) - return (b.isBaseHeader())? null : b; - b = n; - n = f; - } - } - } - - /** - * Returns SimpleImmutableEntry for results of findNear. - * @param key the key - * @param rel the relation -- OR'ed combination of EQ, LT, GT - * @return Entry fitting relation, or null if no such - */ - AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) { - for (;;) { - Node<K,V> n = findNear(key, rel); - if (n == null) - return null; - AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); - if (e != null) - return e; - } - } - - - /* ---------------- Constructors -------------- */ - - /** - * Constructs a new, empty map, sorted according to the - * {@linkplain Comparable natural ordering} of the keys. - */ - public ConcurrentSkipListMap() { - this.comparator = null; - initialize(); - } - - /** - * Constructs a new, empty map, sorted according to the specified - * comparator. - * - * @param comparator the comparator that will be used to order this map. - * If <tt>null</tt>, the {@linkplain Comparable natural - * ordering} of the keys will be used. - */ - public ConcurrentSkipListMap(Comparator<? super K> comparator) { - this.comparator = comparator; - initialize(); - } - - /** - * Constructs a new map containing the same mappings as the given map, - * sorted according to the {@linkplain Comparable natural ordering} of - * the keys. - * - * @param m the map whose mappings are to be placed in this map - * @throws ClassCastException if the keys in <tt>m</tt> are not - * {@link Comparable}, or are not mutually comparable - * @throws NullPointerException if the specified map or any of its keys - * or values are null - */ - public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) { - this.comparator = null; - initialize(); - putAll(m); - } - - /** - * Constructs a new map containing the same mappings and using the - * same ordering as the specified sorted map. - * - * @param m the sorted map whose mappings are to be placed in this - * map, and whose comparator is to be used to sort this map - * @throws NullPointerException if the specified sorted map or any of - * its keys or values are null - */ - public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) { - this.comparator = m.comparator(); - initialize(); - buildFromSorted(m); - } - - /** - * Returns a shallow copy of this <tt>ConcurrentSkipListMap</tt> - * instance. (The keys and values themselves are not cloned.) - * - * @return a shallow copy of this map - */ - public ConcurrentSkipListMap<K,V> clone() { - ConcurrentSkipListMap<K,V> clone = null; - try { - clone = (ConcurrentSkipListMap<K,V>) super.clone(); - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } - - clone.initialize(); - clone.buildFromSorted(this); - return clone; - } - - /** - * Streamlined bulk insertion to initialize from elements of - * given sorted map. Call only from constructor or clone - * method. - */ - private void buildFromSorted(SortedMap<K, ? extends V> map) { - if (map == null) - throw new NullPointerException(); - - HeadIndex<K,V> h = head; - Node<K,V> basepred = h.node; - - // Track the current rightmost node at each level. Uses an - // ArrayList to avoid committing to initial or maximum level. - ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>(); - - // initialize - for (int i = 0; i <= h.level; ++i) - preds.add(null); - Index<K,V> q = h; - for (int i = h.level; i > 0; --i) { - preds.set(i, q); - q = q.down; - } - - Iterator<? extends Map.Entry<? extends K, ? extends V>> it = - map.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<? extends K, ? extends V> e = it.next(); - int j = randomLevel(); - if (j > h.level) j = h.level + 1; - K k = e.getKey(); - V v = e.getValue(); - if (k == null || v == null) - throw new NullPointerException(); - Node<K,V> z = new Node<K,V>(k, v, null); - basepred.next = z; - basepred = z; - if (j > 0) { - Index<K,V> idx = null; - for (int i = 1; i <= j; ++i) { - idx = new Index<K,V>(z, idx, null); - if (i > h.level) - h = new HeadIndex<K,V>(h.node, h, idx, i); - - if (i < preds.size()) { - preds.get(i).right = idx; - preds.set(i, idx); - } else - preds.add(idx); - } - } - } - head = h; - } - - /* ---------------- Serialization -------------- */ - - /** - * Save the state of this map to a stream. - * - * @serialData The key (Object) and value (Object) for each - * key-value mapping represented by the map, followed by - * <tt>null</tt>. The key-value mappings are emitted in key-order - * (as determined by the Comparator, or by the keys' natural - * ordering if no Comparator). - */ - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - // Write out the Comparator and any hidden stuff - s.defaultWriteObject(); - - // Write out keys and values (alternating) - for (Node<K,V> n = findFirst(); n != null; n = n.next) { - V v = n.getValidValue(); - if (v != null) { - s.writeObject(n.key); - s.writeObject(v); - } - } - s.writeObject(null); - } - - /** - * Reconstitute the map from a stream. - */ - private void readObject(final java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - // Read in the Comparator and any hidden stuff - s.defaultReadObject(); - // Reset transients - initialize(); - - /* - * This is nearly identical to buildFromSorted, but is - * distinct because readObject calls can't be nicely adapted - * as the kind of iterator needed by buildFromSorted. (They - * can be, but doing so requires type cheats and/or creation - * of adaptor classes.) It is simpler to just adapt the code. - */ - - HeadIndex<K,V> h = head; - Node<K,V> basepred = h.node; - ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>(); - for (int i = 0; i <= h.level; ++i) - preds.add(null); - Index<K,V> q = h; - for (int i = h.level; i > 0; --i) { - preds.set(i, q); - q = q.down; - } - - for (;;) { - Object k = s.readObject(); - if (k == null) - break; - Object v = s.readObject(); - if (v == null) - throw new NullPointerException(); - K key = (K) k; - V val = (V) v; - int j = randomLevel(); - if (j > h.level) j = h.level + 1; - Node<K,V> z = new Node<K,V>(key, val, null); - basepred.next = z; - basepred = z; - if (j > 0) { - Index<K,V> idx = null; - for (int i = 1; i <= j; ++i) { - idx = new Index<K,V>(z, idx, null); - if (i > h.level) - h = new HeadIndex<K,V>(h.node, h, idx, i); - - if (i < preds.size()) { - preds.get(i).right = idx; - preds.set(i, idx); - } else - preds.add(idx); - } - } - } - head = h; - } - - /* ------ Map API methods ------ */ - - /** - * Returns <tt>true</tt> if this map contains a mapping for the specified - * key. - * - * @param key key whose presence in this map is to be tested - * @return <tt>true</tt> if this map contains a mapping for the specified key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - */ - public boolean containsKey(Object key) { - return doGet(key) != null; - } - - /** - * Returns the value to which the specified key is mapped, - * or {@code null} if this map contains no mapping for the key. - * - * <p>More formally, if this map contains a mapping from a key - * {@code k} to a value {@code v} such that {@code key} compares - * equal to {@code k} according to the map's ordering, then this - * method returns {@code v}; otherwise it returns {@code null}. - * (There can be at most one such mapping.) - * - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - */ - public V get(Object key) { - return doGet(key); - } - - /** - * Associates the specified value with the specified key in this map. - * If the map previously contained a mapping for the key, the old - * value is replaced. - * - * @param key key with which the specified value is to be associated - * @param value value to be associated with the specified key - * @return the previous value associated with the specified key, or - * <tt>null</tt> if there was no mapping for the key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key or value is null - */ - public V put(K key, V value) { - if (value == null) - throw new NullPointerException(); - return doPut(key, value, false); - } - - /** - * Removes the mapping for the specified key from this map if present. - * - * @param key key for which mapping should be removed - * @return the previous value associated with the specified key, or - * <tt>null</tt> if there was no mapping for the key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - */ - public V remove(Object key) { - return doRemove(key, null); - } - - /** - * Returns <tt>true</tt> if this map maps one or more keys to the - * specified value. This operation requires time linear in the - * map size. - * - * @param value value whose presence in this map is to be tested - * @return <tt>true</tt> if a mapping to <tt>value</tt> exists; - * <tt>false</tt> otherwise - * @throws NullPointerException if the specified value is null - */ - public boolean containsValue(Object value) { - if (value == null) - throw new NullPointerException(); - for (Node<K,V> n = findFirst(); n != null; n = n.next) { - V v = n.getValidValue(); - if (v != null && value.equals(v)) - return true; - } - return false; - } - - /** - * Returns the number of key-value mappings in this map. If this map - * contains more than <tt>Integer.MAX_VALUE</tt> elements, it - * returns <tt>Integer.MAX_VALUE</tt>. - * - * <p>Beware that, unlike in most collections, this method is - * <em>NOT</em> a constant-time operation. Because of the - * asynchronous nature of these maps, determining the current - * number of elements requires traversing them all to count them. - * Additionally, it is possible for the size to change during - * execution of this method, in which case the returned result - * will be inaccurate. Thus, this method is typically not very - * useful in concurrent applications. - * - * @return the number of elements in this map - */ - public int size() { - long count = 0; - for (Node<K,V> n = findFirst(); n != null; n = n.next) { - if (n.getValidValue() != null) - ++count; - } - return (count >= Integer.MAX_VALUE)? Integer.MAX_VALUE : (int)count; - } - - /** - * Returns <tt>true</tt> if this map contains no key-value mappings. - * @return <tt>true</tt> if this map contains no key-value mappings - */ - public boolean isEmpty() { - return findFirst() == null; - } - - /** - * Removes all of the mappings from this map. - */ - public void clear() { - initialize(); - } - - /* ---------------- View methods -------------- */ - - /* - * Note: Lazy initialization works for views because view classes - * are stateless/immutable so it doesn't matter wrt correctness if - * more than one is created (which will only rarely happen). Even - * so, the following idiom conservatively ensures that the method - * returns the one it created if it does so, not one created by - * another racing thread. - */ - - /** - * Returns a {@link NavigableSet} view of the keys contained in this map. - * The set's iterator returns the keys in ascending order. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from the map, - * via the {@code Iterator.remove}, {@code Set.remove}, - * {@code removeAll}, {@code retainAll}, and {@code clear} - * operations. It does not support the {@code add} or {@code addAll} - * operations. - * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link 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. - * - * <p>This method is equivalent to method {@code navigableKeySet}. - * - * @return a navigable set view of the keys in this map - */ - public NavigableSet<K> keySet() { - KeySet ks = keySet; - return (ks != null) ? ks : (keySet = new KeySet(this)); - } - - public NavigableSet<K> navigableKeySet() { - KeySet ks = keySet; - return (ks != null) ? ks : (keySet = new KeySet(this)); - } - - /** - * Returns a {@link Collection} view of the values contained in this map. - * The collection's iterator returns the values in ascending order - * of the corresponding keys. - * The collection is backed by the map, so changes to the map are - * reflected in the collection, and vice-versa. The collection - * supports element removal, which removes the corresponding - * mapping from the map, via the <tt>Iterator.remove</tt>, - * <tt>Collection.remove</tt>, <tt>removeAll</tt>, - * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not - * support the <tt>add</tt> or <tt>addAll</tt> operations. - * - * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator - * that will never throw {@link 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. - */ - public Collection<V> values() { - Values vs = values; - return (vs != null) ? vs : (values = new Values(this)); - } - - /** - * Returns a {@link Set} view of the mappings contained in this map. - * The set's iterator returns the entries in ascending key order. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from the map, - * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, - * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt> - * operations. It does not support the <tt>add</tt> or - * <tt>addAll</tt> operations. - * - * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator - * that will never throw {@link 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. - * - * <p>The <tt>Map.Entry</tt> elements returned by - * <tt>iterator.next()</tt> do <em>not</em> support the - * <tt>setValue</tt> operation. - * - * @return a set view of the mappings contained in this map, - * sorted in ascending key order - */ - public Set<Map.Entry<K,V>> entrySet() { - EntrySet es = entrySet; - return (es != null) ? es : (entrySet = new EntrySet(this)); - } - - public ConcurrentNavigableMap<K,V> descendingMap() { - ConcurrentNavigableMap<K,V> dm = descendingMap; - return (dm != null) ? dm : (descendingMap = new SubMap<K,V> - (this, null, false, null, false, true)); - } - - public NavigableSet<K> descendingKeySet() { - return descendingMap().navigableKeySet(); - } - - /* ---------------- AbstractMap Overrides -------------- */ - - /** - * Compares the specified object with this map for equality. - * Returns <tt>true</tt> if the given object is also a map and the - * two maps represent the same mappings. More formally, two maps - * <tt>m1</tt> and <tt>m2</tt> represent the same mappings if - * <tt>m1.entrySet().equals(m2.entrySet())</tt>. This - * operation may return misleading results if either map is - * concurrently modified during execution of this method. - * - * @param o object to be compared for equality with this map - * @return <tt>true</tt> if the specified object is equal to this map - */ - public boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof Map)) - return false; - Map<?,?> m = (Map<?,?>) o; - try { - for (Map.Entry<K,V> e : this.entrySet()) - if (! e.getValue().equals(m.get(e.getKey()))) - return false; - for (Map.Entry<?,?> e : m.entrySet()) { - Object k = e.getKey(); - Object v = e.getValue(); - if (k == null || v == null || !v.equals(get(k))) - return false; - } - return true; - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { - return false; - } - } - - /* ------ ConcurrentMap API methods ------ */ - - /** - * {@inheritDoc} - * - * @return the previous value associated with the specified key, - * or <tt>null</tt> if there was no mapping for the key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key or value is null - */ - public V putIfAbsent(K key, V value) { - if (value == null) - throw new NullPointerException(); - return doPut(key, value, true); - } - - /** - * {@inheritDoc} - * - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key is null - */ - public boolean remove(Object key, Object value) { - if (key == null) - throw new NullPointerException(); - if (value == null) - return false; - return doRemove(key, value) != null; - } - - /** - * {@inheritDoc} - * - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if any of the arguments are null - */ - public boolean replace(K key, V oldValue, V newValue) { - if (oldValue == null || newValue == null) - throw new NullPointerException(); - Comparable<? super K> k = comparable(key); - for (;;) { - Node<K,V> n = findNode(k); - if (n == null) - return false; - Object v = n.value; - if (v != null) { - if (!oldValue.equals(v)) - return false; - if (n.casValue(v, newValue)) - return true; - } - } - } - - /** - * {@inheritDoc} - * - * @return the previous value associated with the specified key, - * or <tt>null</tt> if there was no mapping for the key - * @throws ClassCastException if the specified key cannot be compared - * with the keys currently in the map - * @throws NullPointerException if the specified key or value is null - */ - public V replace(K key, V value) { - if (value == null) - throw new NullPointerException(); - Comparable<? super K> k = comparable(key); - for (;;) { - Node<K,V> n = findNode(k); - if (n == null) - return null; - Object v = n.value; - if (v != null && n.casValue(v, value)) - return (V)v; - } - } - - /* ------ SortedMap API methods ------ */ - - public Comparator<? super K> comparator() { - return comparator; - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public K firstKey() { - Node<K,V> n = findFirst(); - if (n == null) - throw new NoSuchElementException(); - return n.key; - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public K lastKey() { - Node<K,V> n = findLast(); - if (n == null) - throw new NoSuchElementException(); - return n.key; - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code fromKey} or {@code toKey} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public ConcurrentNavigableMap<K,V> subMap(K fromKey, - boolean fromInclusive, - K toKey, - boolean toInclusive) { - if (fromKey == null || toKey == null) - throw new NullPointerException(); - return new SubMap<K,V> - (this, fromKey, fromInclusive, toKey, toInclusive, false); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code toKey} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public ConcurrentNavigableMap<K,V> headMap(K toKey, - boolean inclusive) { - if (toKey == null) - throw new NullPointerException(); - return new SubMap<K,V> - (this, null, false, toKey, inclusive, false); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code fromKey} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public ConcurrentNavigableMap<K,V> tailMap(K fromKey, - boolean inclusive) { - if (fromKey == null) - throw new NullPointerException(); - return new SubMap<K,V> - (this, fromKey, inclusive, null, false, false); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code fromKey} or {@code toKey} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code toKey} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public ConcurrentNavigableMap<K,V> headMap(K toKey) { - return headMap(toKey, false); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code fromKey} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public ConcurrentNavigableMap<K,V> tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - /* ---------------- Relational operations -------------- */ - - /** - * Returns a key-value mapping associated with the greatest key - * strictly less than the given key, or <tt>null</tt> if there is - * no such key. The returned entry does <em>not</em> support the - * <tt>Entry.setValue</tt> method. - * - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified key is null - */ - public Map.Entry<K,V> lowerEntry(K key) { - return getNear(key, LT); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified key is null - */ - public K lowerKey(K key) { - Node<K,V> n = findNear(key, LT); - return (n == null)? null : n.key; - } - - /** - * Returns a key-value mapping associated with the greatest key - * less than or equal to the given key, or <tt>null</tt> if there - * is no such key. The returned entry does <em>not</em> support - * the <tt>Entry.setValue</tt> method. - * - * @param key the key - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified key is null - */ - public Map.Entry<K,V> floorEntry(K key) { - return getNear(key, LT|EQ); - } - - /** - * @param key the key - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified key is null - */ - public K floorKey(K key) { - Node<K,V> n = findNear(key, LT|EQ); - return (n == null)? null : n.key; - } - - /** - * Returns a key-value mapping associated with the least key - * greater than or equal to the given key, or <tt>null</tt> if - * there is no such entry. The returned entry does <em>not</em> - * support the <tt>Entry.setValue</tt> method. - * - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified key is null - */ - public Map.Entry<K,V> ceilingEntry(K key) { - return getNear(key, GT|EQ); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified key is null - */ - public K ceilingKey(K key) { - Node<K,V> n = findNear(key, GT|EQ); - return (n == null)? null : n.key; - } - - /** - * Returns a key-value mapping associated with the least key - * strictly greater than the given key, or <tt>null</tt> if there - * is no such key. The returned entry does <em>not</em> support - * the <tt>Entry.setValue</tt> method. - * - * @param key the key - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified key is null - */ - public Map.Entry<K,V> higherEntry(K key) { - return getNear(key, GT); - } - - /** - * @param key the key - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified key is null - */ - public K higherKey(K key) { - Node<K,V> n = findNear(key, GT); - return (n == null)? null : n.key; - } - - /** - * Returns a key-value mapping associated with the least - * key in this map, or <tt>null</tt> if the map is empty. - * The returned entry does <em>not</em> support - * the <tt>Entry.setValue</tt> method. - */ - public Map.Entry<K,V> firstEntry() { - for (;;) { - Node<K,V> n = findFirst(); - if (n == null) - return null; - AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); - if (e != null) - return e; - } - } - - /** - * Returns a key-value mapping associated with the greatest - * key in this map, or <tt>null</tt> if the map is empty. - * The returned entry does <em>not</em> support - * the <tt>Entry.setValue</tt> method. - */ - public Map.Entry<K,V> lastEntry() { - for (;;) { - Node<K,V> n = findLast(); - if (n == null) - return null; - AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); - if (e != null) - return e; - } - } - - /** - * Removes and returns a key-value mapping associated with - * the least key in this map, or <tt>null</tt> if the map is empty. - * The returned entry does <em>not</em> support - * the <tt>Entry.setValue</tt> method. - */ - public Map.Entry<K,V> pollFirstEntry() { - return doRemoveFirstEntry(); - } - - /** - * Removes and returns a key-value mapping associated with - * the greatest key in this map, or <tt>null</tt> if the map is empty. - * The returned entry does <em>not</em> support - * the <tt>Entry.setValue</tt> method. - */ - public Map.Entry<K,V> pollLastEntry() { - return doRemoveLastEntry(); - } - - - /* ---------------- Iterators -------------- */ - - /** - * Base of iterator classes: - */ - abstract class Iter<T> implements Iterator<T> { - /** the last node returned by next() */ - Node<K,V> lastReturned; - /** the next node to return from next(); */ - Node<K,V> next; - /** Cache of next value field to maintain weak consistency */ - V nextValue; - - /** Initializes ascending iterator for entire range. */ - Iter() { - for (;;) { - next = findFirst(); - if (next == null) - break; - Object x = next.value; - if (x != null && x != next) { - nextValue = (V) x; - break; - } - } - } - - public final boolean hasNext() { - return next != null; - } - - /** Advances next to higher entry. */ - final void advance() { - if ((lastReturned = next) == null) - throw new NoSuchElementException(); - for (;;) { - next = next.next; - if (next == null) - break; - Object x = next.value; - if (x != null && x != next) { - nextValue = (V) x; - break; - } - } - } - - public void remove() { - Node<K,V> l = lastReturned; - if (l == null) - throw new IllegalStateException(); - // It would not be worth all of the overhead to directly - // unlink from here. Using remove is fast enough. - ConcurrentSkipListMap.this.remove(l.key); - lastReturned = null; - } - - } - - final class ValueIterator extends Iter<V> { - public V next() { - V v = nextValue; - advance(); - return v; - } - } - - final class KeyIterator extends Iter<K> { - public K next() { - Node<K,V> n = next; - advance(); - return n.key; - } - } - - final class EntryIterator extends Iter<Map.Entry<K,V>> { - public Map.Entry<K,V> next() { - Node<K,V> n = next; - V v = nextValue; - advance(); - return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); - } - } - - // Factory methods for iterators needed by ConcurrentSkipListSet etc - - Iterator<K> keyIterator() { - return new KeyIterator(); - } - - Iterator<V> valueIterator() { - return new ValueIterator(); - } - - Iterator<Map.Entry<K,V>> entryIterator() { - return new EntryIterator(); - } - - /* ---------------- View Classes -------------- */ - - /* - * View classes are static, delegating to a ConcurrentNavigableMap - * to allow use by SubMaps, which outweighs the ugliness of - * needing type-tests for Iterator methods. - */ - - static final <E> List<E> toList(Collection<E> c) { - // Using size() here would be a pessimization. - List<E> list = new ArrayList<E>(); - for (E e : c) - list.add(e); - return list; - } - - static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> { - private final ConcurrentNavigableMap<E,Object> m; - KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; } - public int size() { return m.size(); } - public boolean isEmpty() { return m.isEmpty(); } - public boolean contains(Object o) { return m.containsKey(o); } - public boolean remove(Object o) { return m.remove(o) != null; } - public void clear() { m.clear(); } - public E lower(E e) { return m.lowerKey(e); } - public E floor(E e) { return m.floorKey(e); } - public E ceiling(E e) { return m.ceilingKey(e); } - public E higher(E e) { return m.higherKey(e); } - public Comparator<? super E> comparator() { return m.comparator(); } - public E first() { return m.firstKey(); } - public E last() { return m.lastKey(); } - public E pollFirst() { - Map.Entry<E,Object> e = m.pollFirstEntry(); - return e == null? null : e.getKey(); - } - public E pollLast() { - Map.Entry<E,Object> e = m.pollLastEntry(); - return e == null? null : e.getKey(); - } - public Iterator<E> iterator() { - if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap<E,Object>)m).keyIterator(); - else - return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator(); - } - public boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof Set)) - return false; - Collection<?> c = (Collection<?>) o; - try { - return containsAll(c) && c.containsAll(this); - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { - return false; - } - } - public Object[] toArray() { return toList(this).toArray(); } - public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } - public Iterator<E> descendingIterator() { - return descendingSet().iterator(); - } - public NavigableSet<E> subSet(E fromElement, - boolean fromInclusive, - E toElement, - boolean toInclusive) { - return new ConcurrentSkipListSet<E> - (m.subMap(fromElement, fromInclusive, - toElement, toInclusive)); - } - public NavigableSet<E> headSet(E toElement, boolean inclusive) { - return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive)); - } - public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { - return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive)); - } - public NavigableSet<E> subSet(E fromElement, E toElement) { - return subSet(fromElement, true, toElement, false); - } - public NavigableSet<E> headSet(E toElement) { - return headSet(toElement, false); - } - public NavigableSet<E> tailSet(E fromElement) { - return tailSet(fromElement, true); - } - public NavigableSet<E> descendingSet() { - return new ConcurrentSkipListSet(m.descendingMap()); - } - } - - static final class Values<E> extends AbstractCollection<E> { - private final ConcurrentNavigableMap<Object, E> m; - Values(ConcurrentNavigableMap<Object, E> map) { - m = map; - } - public Iterator<E> iterator() { - if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap<Object,E>)m).valueIterator(); - else - return ((SubMap<Object,E>)m).valueIterator(); - } - public boolean isEmpty() { - return m.isEmpty(); - } - public int size() { - return m.size(); - } - public boolean contains(Object o) { - return m.containsValue(o); - } - public void clear() { - m.clear(); - } - public Object[] toArray() { return toList(this).toArray(); } - public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } - } - - static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> { - private final ConcurrentNavigableMap<K1, V1> m; - EntrySet(ConcurrentNavigableMap<K1, V1> map) { - m = map; - } - - public Iterator<Map.Entry<K1,V1>> iterator() { - if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator(); - else - return ((SubMap<K1,V1>)m).entryIterator(); - } - - public boolean contains(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o; - V1 v = m.get(e.getKey()); - return v != null && v.equals(e.getValue()); - } - public boolean remove(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o; - return m.remove(e.getKey(), - e.getValue()); - } - public boolean isEmpty() { - return m.isEmpty(); - } - public int size() { - return m.size(); - } - public void clear() { - m.clear(); - } - public boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof Set)) - return false; - Collection<?> c = (Collection<?>) o; - try { - return containsAll(c) && c.containsAll(this); - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { - return false; - } - } - public Object[] toArray() { return toList(this).toArray(); } - public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } - } - - /** - * Submaps returned by {@link ConcurrentSkipListMap} submap operations - * represent a subrange of mappings of their underlying - * maps. Instances of this class support all methods of their - * underlying maps, differing in that mappings outside their range are - * ignored, and attempts to add mappings outside their ranges result - * in {@link IllegalArgumentException}. Instances of this class are - * constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and - * <tt>tailMap</tt> methods of their underlying maps. - * - * @serial include - */ - static final class SubMap<K,V> extends AbstractMap<K,V> - implements ConcurrentNavigableMap<K,V>, Cloneable, - java.io.Serializable { - private static final long serialVersionUID = -7647078645895051609L; - - /** Underlying map */ - private final ConcurrentSkipListMap<K,V> m; - /** lower bound key, or null if from start */ - private final K lo; - /** upper bound key, or null if to end */ - private final K hi; - /** inclusion flag for lo */ - private final boolean loInclusive; - /** inclusion flag for hi */ - private final boolean hiInclusive; - /** direction */ - private final boolean isDescending; - - // Lazily initialized view holders - private transient KeySet<K> keySetView; - private transient Set<Map.Entry<K,V>> entrySetView; - private transient Collection<V> valuesView; - - /** - * Creates a new submap, initializing all fields - */ - SubMap(ConcurrentSkipListMap<K,V> map, - K fromKey, boolean fromInclusive, - K toKey, boolean toInclusive, - boolean isDescending) { - if (fromKey != null && toKey != null && - map.compare(fromKey, toKey) > 0) - throw new IllegalArgumentException("inconsistent range"); - this.m = map; - this.lo = fromKey; - this.hi = toKey; - this.loInclusive = fromInclusive; - this.hiInclusive = toInclusive; - this.isDescending = isDescending; - } - - /* ---------------- Utilities -------------- */ - - private boolean tooLow(K key) { - if (lo != null) { - int c = m.compare(key, lo); - if (c < 0 || (c == 0 && !loInclusive)) - return true; - } - return false; - } - - private boolean tooHigh(K key) { - if (hi != null) { - int c = m.compare(key, hi); - if (c > 0 || (c == 0 && !hiInclusive)) - return true; - } - return false; - } - - private boolean inBounds(K key) { - return !tooLow(key) && !tooHigh(key); - } - - private void checkKeyBounds(K key) throws IllegalArgumentException { - if (key == null) - throw new NullPointerException(); - if (!inBounds(key)) - throw new IllegalArgumentException("key out of range"); - } - - /** - * Returns true if node key is less than upper bound of range - */ - private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) { - if (n == null) - return false; - if (hi == null) - return true; - K k = n.key; - if (k == null) // pass by markers and headers - return true; - int c = m.compare(k, hi); - if (c > 0 || (c == 0 && !hiInclusive)) - return false; - return true; - } - - /** - * Returns lowest node. This node might not be in range, so - * most usages need to check bounds - */ - private ConcurrentSkipListMap.Node<K,V> loNode() { - if (lo == null) - return m.findFirst(); - else if (loInclusive) - return m.findNear(lo, m.GT|m.EQ); - else - return m.findNear(lo, m.GT); - } - - /** - * Returns highest node. This node might not be in range, so - * most usages need to check bounds - */ - private ConcurrentSkipListMap.Node<K,V> hiNode() { - if (hi == null) - return m.findLast(); - else if (hiInclusive) - return m.findNear(hi, m.LT|m.EQ); - else - return m.findNear(hi, m.LT); - } - - /** - * Returns lowest absolute key (ignoring directonality) - */ - private K lowestKey() { - ConcurrentSkipListMap.Node<K,V> n = loNode(); - if (isBeforeEnd(n)) - return n.key; - else - throw new NoSuchElementException(); - } - - /** - * Returns highest absolute key (ignoring directonality) - */ - private K highestKey() { - ConcurrentSkipListMap.Node<K,V> n = hiNode(); - if (n != null) { - K last = n.key; - if (inBounds(last)) - return last; - } - throw new NoSuchElementException(); - } - - private Map.Entry<K,V> lowestEntry() { - for (;;) { - ConcurrentSkipListMap.Node<K,V> n = loNode(); - if (!isBeforeEnd(n)) - return null; - Map.Entry<K,V> e = n.createSnapshot(); - if (e != null) - return e; - } - } - - private Map.Entry<K,V> highestEntry() { - for (;;) { - ConcurrentSkipListMap.Node<K,V> n = hiNode(); - if (n == null || !inBounds(n.key)) - return null; - Map.Entry<K,V> e = n.createSnapshot(); - if (e != null) - return e; - } - } - - private Map.Entry<K,V> removeLowest() { - for (;;) { - Node<K,V> n = loNode(); - if (n == null) - return null; - K k = n.key; - if (!inBounds(k)) - return null; - V v = m.doRemove(k, null); - if (v != null) - return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); - } - } - - private Map.Entry<K,V> removeHighest() { - for (;;) { - Node<K,V> n = hiNode(); - if (n == null) - return null; - K k = n.key; - if (!inBounds(k)) - return null; - V v = m.doRemove(k, null); - if (v != null) - return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); - } - } - - /** - * Submap version of ConcurrentSkipListMap.getNearEntry - */ - private Map.Entry<K,V> getNearEntry(K key, int rel) { - if (isDescending) { // adjust relation for direction - if ((rel & m.LT) == 0) - rel |= m.LT; - else - rel &= ~m.LT; - } - if (tooLow(key)) - return ((rel & m.LT) != 0)? null : lowestEntry(); - if (tooHigh(key)) - return ((rel & m.LT) != 0)? highestEntry() : null; - for (;;) { - Node<K,V> n = m.findNear(key, rel); - if (n == null || !inBounds(n.key)) - return null; - K k = n.key; - V v = n.getValidValue(); - if (v != null) - return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); - } - } - - // Almost the same as getNearEntry, except for keys - private K getNearKey(K key, int rel) { - if (isDescending) { // adjust relation for direction - if ((rel & m.LT) == 0) - rel |= m.LT; - else - rel &= ~m.LT; - } - if (tooLow(key)) { - if ((rel & m.LT) == 0) { - ConcurrentSkipListMap.Node<K,V> n = loNode(); - if (isBeforeEnd(n)) - return n.key; - } - return null; - } - if (tooHigh(key)) { - if ((rel & m.LT) != 0) { - ConcurrentSkipListMap.Node<K,V> n = hiNode(); - if (n != null) { - K last = n.key; - if (inBounds(last)) - return last; - } - } - return null; - } - for (;;) { - Node<K,V> n = m.findNear(key, rel); - if (n == null || !inBounds(n.key)) - return null; - K k = n.key; - V v = n.getValidValue(); - if (v != null) - return k; - } - } - - /* ---------------- Map API methods -------------- */ - - public boolean containsKey(Object key) { - if (key == null) throw new NullPointerException(); - K k = (K)key; - return inBounds(k) && m.containsKey(k); - } - - public V get(Object key) { - if (key == null) throw new NullPointerException(); - K k = (K)key; - return ((!inBounds(k)) ? null : m.get(k)); - } - - public V put(K key, V value) { - checkKeyBounds(key); - return m.put(key, value); - } - - public V remove(Object key) { - K k = (K)key; - return (!inBounds(k))? null : m.remove(k); - } - - public int size() { - long count = 0; - for (ConcurrentSkipListMap.Node<K,V> n = loNode(); - isBeforeEnd(n); - n = n.next) { - if (n.getValidValue() != null) - ++count; - } - return count >= Integer.MAX_VALUE? Integer.MAX_VALUE : (int)count; - } - - public boolean isEmpty() { - return !isBeforeEnd(loNode()); - } - - public boolean containsValue(Object value) { - if (value == null) - throw new NullPointerException(); - for (ConcurrentSkipListMap.Node<K,V> n = loNode(); - isBeforeEnd(n); - n = n.next) { - V v = n.getValidValue(); - if (v != null && value.equals(v)) - return true; - } - return false; - } - - public void clear() { - for (ConcurrentSkipListMap.Node<K,V> n = loNode(); - isBeforeEnd(n); - n = n.next) { - if (n.getValidValue() != null) - m.remove(n.key); - } - } - - /* ---------------- ConcurrentMap API methods -------------- */ - - public V putIfAbsent(K key, V value) { - checkKeyBounds(key); - return m.putIfAbsent(key, value); - } - - public boolean remove(Object key, Object value) { - K k = (K)key; - return inBounds(k) && m.remove(k, value); - } - - public boolean replace(K key, V oldValue, V newValue) { - checkKeyBounds(key); - return m.replace(key, oldValue, newValue); - } - - public V replace(K key, V value) { - checkKeyBounds(key); - return m.replace(key, value); - } - - /* ---------------- SortedMap API methods -------------- */ - - public Comparator<? super K> comparator() { - Comparator<? super K> cmp = m.comparator(); - if (isDescending) - return Collections.reverseOrder(cmp); - else - return cmp; - } - - /** - * Utility to create submaps, where given bounds override - * unbounded(null) ones and/or are checked against bounded ones. - */ - private SubMap<K,V> newSubMap(K fromKey, - boolean fromInclusive, - K toKey, - boolean toInclusive) { - if (isDescending) { // flip senses - K tk = fromKey; - fromKey = toKey; - toKey = tk; - boolean ti = fromInclusive; - fromInclusive = toInclusive; - toInclusive = ti; - } - if (lo != null) { - if (fromKey == null) { - fromKey = lo; - fromInclusive = loInclusive; - } - else { - int c = m.compare(fromKey, lo); - if (c < 0 || (c == 0 && !loInclusive && fromInclusive)) - throw new IllegalArgumentException("key out of range"); - } - } - if (hi != null) { - if (toKey == null) { - toKey = hi; - toInclusive = hiInclusive; - } - else { - int c = m.compare(toKey, hi); - if (c > 0 || (c == 0 && !hiInclusive && toInclusive)) - throw new IllegalArgumentException("key out of range"); - } - } - return new SubMap<K,V>(m, fromKey, fromInclusive, - toKey, toInclusive, isDescending); - } - - public SubMap<K,V> subMap(K fromKey, - boolean fromInclusive, - K toKey, - boolean toInclusive) { - if (fromKey == null || toKey == null) - throw new NullPointerException(); - return newSubMap(fromKey, fromInclusive, toKey, toInclusive); - } - - public SubMap<K,V> headMap(K toKey, - boolean inclusive) { - if (toKey == null) - throw new NullPointerException(); - return newSubMap(null, false, toKey, inclusive); - } - - public SubMap<K,V> tailMap(K fromKey, - boolean inclusive) { - if (fromKey == null) - throw new NullPointerException(); - return newSubMap(fromKey, inclusive, null, false); - } - - public SubMap<K,V> subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - public SubMap<K,V> headMap(K toKey) { - return headMap(toKey, false); - } - - public SubMap<K,V> tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - public SubMap<K,V> descendingMap() { - return new SubMap<K,V>(m, lo, loInclusive, - hi, hiInclusive, !isDescending); - } - - /* ---------------- Relational methods -------------- */ - - public Map.Entry<K,V> ceilingEntry(K key) { - return getNearEntry(key, (m.GT|m.EQ)); - } - - public K ceilingKey(K key) { - return getNearKey(key, (m.GT|m.EQ)); - } - - public Map.Entry<K,V> lowerEntry(K key) { - return getNearEntry(key, (m.LT)); - } - - public K lowerKey(K key) { - return getNearKey(key, (m.LT)); - } - - public Map.Entry<K,V> floorEntry(K key) { - return getNearEntry(key, (m.LT|m.EQ)); - } - - public K floorKey(K key) { - return getNearKey(key, (m.LT|m.EQ)); - } - - public Map.Entry<K,V> higherEntry(K key) { - return getNearEntry(key, (m.GT)); - } - - public K higherKey(K key) { - return getNearKey(key, (m.GT)); - } - - public K firstKey() { - return isDescending? highestKey() : lowestKey(); - } - - public K lastKey() { - return isDescending? lowestKey() : highestKey(); - } - - public Map.Entry<K,V> firstEntry() { - return isDescending? highestEntry() : lowestEntry(); - } - - public Map.Entry<K,V> lastEntry() { - return isDescending? lowestEntry() : highestEntry(); - } - - public Map.Entry<K,V> pollFirstEntry() { - return isDescending? removeHighest() : removeLowest(); - } - - public Map.Entry<K,V> pollLastEntry() { - return isDescending? removeLowest() : removeHighest(); - } - - /* ---------------- Submap Views -------------- */ - - public NavigableSet<K> keySet() { - KeySet<K> ks = keySetView; - return (ks != null) ? ks : (keySetView = new KeySet(this)); - } - - public NavigableSet<K> navigableKeySet() { - KeySet<K> ks = keySetView; - return (ks != null) ? ks : (keySetView = new KeySet(this)); - } - - public Collection<V> values() { - Collection<V> vs = valuesView; - return (vs != null) ? vs : (valuesView = new Values(this)); - } - - public Set<Map.Entry<K,V>> entrySet() { - Set<Map.Entry<K,V>> es = entrySetView; - return (es != null) ? es : (entrySetView = new EntrySet(this)); - } - - public NavigableSet<K> descendingKeySet() { - return descendingMap().navigableKeySet(); - } - - Iterator<K> keyIterator() { - return new SubMapKeyIterator(); - } - - Iterator<V> valueIterator() { - return new SubMapValueIterator(); - } - - Iterator<Map.Entry<K,V>> entryIterator() { - return new SubMapEntryIterator(); - } - - /** - * Variant of main Iter class to traverse through submaps. - */ - abstract class SubMapIter<T> implements Iterator<T> { - /** the last node returned by next() */ - Node<K,V> lastReturned; - /** the next node to return from next(); */ - Node<K,V> next; - /** Cache of next value field to maintain weak consistency */ - V nextValue; - - SubMapIter() { - for (;;) { - next = isDescending ? hiNode() : loNode(); - if (next == null) - break; - Object x = next.value; - if (x != null && x != next) { - if (! inBounds(next.key)) - next = null; - else - nextValue = (V) x; - break; - } - } - } - - public final boolean hasNext() { - return next != null; - } - - final void advance() { - if ((lastReturned = next) == null) - throw new NoSuchElementException(); - if (isDescending) - descend(); - else - ascend(); - } - - private void ascend() { - for (;;) { - next = next.next; - if (next == null) - break; - Object x = next.value; - if (x != null && x != next) { - if (tooHigh(next.key)) - next = null; - else - nextValue = (V) x; - break; - } - } - } - - private void descend() { - for (;;) { - next = m.findNear(lastReturned.key, LT); - if (next == null) - break; - Object x = next.value; - if (x != null && x != next) { - if (tooLow(next.key)) - next = null; - else - nextValue = (V) x; - break; - } - } - } - - public void remove() { - Node<K,V> l = lastReturned; - if (l == null) - throw new IllegalStateException(); - m.remove(l.key); - lastReturned = null; - } - - } - - final class SubMapValueIterator extends SubMapIter<V> { - public V next() { - V v = nextValue; - advance(); - return v; - } - } - - final class SubMapKeyIterator extends SubMapIter<K> { - public K next() { - Node<K,V> n = next; - advance(); - return n.key; - } - } - - final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> { - public Map.Entry<K,V> next() { - Node<K,V> n = next; - V v = nextValue; - advance(); - return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); - } - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListSet.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListSet.java deleted file mode 100644 index 7fd1c76..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListSet.java +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; -import sun.misc.Unsafe; - -/** - * A scalable concurrent {@link NavigableSet} implementation based on - * a {@link ConcurrentSkipListMap}. The elements of the set are kept - * sorted according to their {@linkplain Comparable natural ordering}, - * or by a {@link Comparator} provided at set creation time, depending - * on which constructor is used. - * - * <p>This implementation provides expected average <i>log(n)</i> time - * cost for the <tt>contains</tt>, <tt>add</tt>, and <tt>remove</tt> - * operations and their variants. Insertion, removal, and access - * operations safely execute concurrently by multiple threads. - * Iterators are <i>weakly consistent</i>, returning elements - * reflecting the state of the set at some point at or since the - * creation of the iterator. They do <em>not</em> throw {@link - * ConcurrentModificationException}, and may proceed concurrently with - * other operations. Ascending ordered views and their iterators are - * faster than descending ones. - * - * <p>Beware that, unlike in most collections, the <tt>size</tt> - * method is <em>not</em> a constant-time operation. Because of the - * asynchronous nature of these sets, determining the current number - * of elements requires a traversal of the elements. Additionally, the - * bulk operations <tt>addAll</tt>, <tt>removeAll</tt>, - * <tt>retainAll</tt>, and <tt>containsAll</tt> are <em>not</em> - * guaranteed to be performed atomically. For example, an iterator - * operating concurrently with an <tt>addAll</tt> operation might view - * only some of the added elements. - * - * <p>This class and its iterators implement all of the - * <em>optional</em> methods of the {@link Set} and {@link Iterator} - * interfaces. Like most other concurrent collection implementations, - * this class does not permit the use of <tt>null</tt> elements, - * because <tt>null</tt> arguments and return values cannot be reliably - * distinguished from the absence of elements. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @author Doug Lea - * @param <E> the type of elements maintained by this set - * @since 1.6 - */ -public class ConcurrentSkipListSet<E> - extends AbstractSet<E> - implements NavigableSet<E>, Cloneable, java.io.Serializable { - - private static final long serialVersionUID = -2479143111061671589L; - - /** - * The underlying map. Uses Boolean.TRUE as value for each - * element. This field is declared final for the sake of thread - * safety, which entails some ugliness in clone() - */ - private final ConcurrentNavigableMap<E,Object> m; - - /** - * Constructs a new, empty set that orders its elements according to - * their {@linkplain Comparable natural ordering}. - */ - public ConcurrentSkipListSet() { - m = new ConcurrentSkipListMap<E,Object>(); - } - - /** - * Constructs a new, empty set that orders its elements according to - * the specified comparator. - * - * @param comparator the comparator that will be used to order this set. - * If <tt>null</tt>, the {@linkplain Comparable natural - * ordering} of the elements will be used. - */ - public ConcurrentSkipListSet(Comparator<? super E> comparator) { - m = new ConcurrentSkipListMap<E,Object>(comparator); - } - - /** - * Constructs a new set containing the elements in the specified - * collection, that orders its elements according to their - * {@linkplain Comparable natural ordering}. - * - * @param c The elements that will comprise the new set - * @throws ClassCastException if the elements in <tt>c</tt> are - * not {@link Comparable}, or are not mutually comparable - * @throws NullPointerException if the specified collection or any - * of its elements are null - */ - public ConcurrentSkipListSet(Collection<? extends E> c) { - m = new ConcurrentSkipListMap<E,Object>(); - addAll(c); - } - - /** - * Constructs a new set containing the same elements and using the - * same ordering as the specified sorted set. - * - * @param s sorted set whose elements will comprise the new set - * @throws NullPointerException if the specified sorted set or any - * of its elements are null - */ - public ConcurrentSkipListSet(SortedSet<E> s) { - m = new ConcurrentSkipListMap<E,Object>(s.comparator()); - addAll(s); - } - - /** - * For use by submaps - */ - ConcurrentSkipListSet(ConcurrentNavigableMap<E,Object> m) { - this.m = m; - } - - /** - * Returns a shallow copy of this <tt>ConcurrentSkipListSet</tt> - * instance. (The elements themselves are not cloned.) - * - * @return a shallow copy of this set - */ - public ConcurrentSkipListSet<E> clone() { - ConcurrentSkipListSet<E> clone = null; - try { - clone = (ConcurrentSkipListSet<E>) super.clone(); - clone.setMap(new ConcurrentSkipListMap(m)); - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } - - return clone; - } - - /* ---------------- Set operations -------------- */ - - /** - * Returns the number of elements in this set. If this set - * contains more than <tt>Integer.MAX_VALUE</tt> elements, it - * returns <tt>Integer.MAX_VALUE</tt>. - * - * <p>Beware that, unlike in most collections, this method is - * <em>NOT</em> a constant-time operation. Because of the - * asynchronous nature of these sets, determining the current - * number of elements requires traversing them all to count them. - * Additionally, it is possible for the size to change during - * execution of this method, in which case the returned result - * will be inaccurate. Thus, this method is typically not very - * useful in concurrent applications. - * - * @return the number of elements in this set - */ - public int size() { - return m.size(); - } - - /** - * Returns <tt>true</tt> if this set contains no elements. - * @return <tt>true</tt> if this set contains no elements - */ - public boolean isEmpty() { - return m.isEmpty(); - } - - /** - * Returns <tt>true</tt> if this set contains the specified element. - * More formally, returns <tt>true</tt> if and only if this set - * contains an element <tt>e</tt> such that <tt>o.equals(e)</tt>. - * - * @param o object to be checked for containment in this set - * @return <tt>true</tt> if this set contains the specified element - * @throws ClassCastException if the specified element cannot be - * compared with the elements currently in this set - * @throws NullPointerException if the specified element is null - */ - public boolean contains(Object o) { - return m.containsKey(o); - } - - /** - * Adds the specified element to this set if it is not already present. - * More formally, adds the specified element <tt>e</tt> to this set if - * the set contains no element <tt>e2</tt> such that <tt>e.equals(e2)</tt>. - * If this set already contains the element, the call leaves the set - * unchanged and returns <tt>false</tt>. - * - * @param e element to be added to this set - * @return <tt>true</tt> if this set did not already contain the - * specified element - * @throws ClassCastException if <tt>e</tt> cannot be compared - * with the elements currently in this set - * @throws NullPointerException if the specified element is null - */ - public boolean add(E e) { - return m.putIfAbsent(e, Boolean.TRUE) == null; - } - - /** - * Removes the specified element from this set if it is present. - * More formally, removes an element <tt>e</tt> such that - * <tt>o.equals(e)</tt>, if this set contains such an element. - * Returns <tt>true</tt> if this set contained the element (or - * equivalently, if this set changed as a result of the call). - * (This set will not contain the element once the call returns.) - * - * @param o object to be removed from this set, if present - * @return <tt>true</tt> if this set contained the specified element - * @throws ClassCastException if <tt>o</tt> cannot be compared - * with the elements currently in this set - * @throws NullPointerException if the specified element is null - */ - public boolean remove(Object o) { - return m.remove(o, Boolean.TRUE); - } - - /** - * Removes all of the elements from this set. - */ - public void clear() { - m.clear(); - } - - /** - * Returns an iterator over the elements in this set in ascending order. - * - * @return an iterator over the elements in this set in ascending order - */ - public Iterator<E> iterator() { - return m.navigableKeySet().iterator(); - } - - /** - * Returns an iterator over the elements in this set in descending order. - * - * @return an iterator over the elements in this set in descending order - */ - public Iterator<E> descendingIterator() { - return m.descendingKeySet().iterator(); - } - - - /* ---------------- AbstractSet Overrides -------------- */ - - /** - * Compares the specified object with this set for equality. Returns - * <tt>true</tt> if the specified object is also a set, the two sets - * have the same size, and every member of the specified set is - * contained in this set (or equivalently, every member of this set is - * contained in the specified set). This definition ensures that the - * equals method works properly across different implementations of the - * set interface. - * - * @param o the object to be compared for equality with this set - * @return <tt>true</tt> if the specified object is equal to this set - */ - public boolean equals(Object o) { - // Override AbstractSet version to avoid calling size() - if (o == this) - return true; - if (!(o instanceof Set)) - return false; - Collection<?> c = (Collection<?>) o; - try { - return containsAll(c) && c.containsAll(this); - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { - return false; - } - } - - /** - * Removes from this set all of its elements that are contained in - * the specified collection. If the specified collection is also - * a set, this operation effectively modifies this set so that its - * value is the <i>asymmetric set difference</i> of the two sets. - * - * @param c collection containing elements to be removed from this set - * @return <tt>true</tt> if this set changed as a result of the call - * @throws ClassCastException if the types of one or more elements in this - * set are incompatible with the specified collection - * @throws NullPointerException if the specified collection or any - * of its elements are null - */ - public boolean removeAll(Collection<?> c) { - // Override AbstractSet version to avoid unnecessary call to size() - boolean modified = false; - for (Iterator<?> i = c.iterator(); i.hasNext(); ) - if (remove(i.next())) - modified = true; - return modified; - } - - /* ---------------- Relational operations -------------- */ - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - */ - public E lower(E e) { - return m.lowerKey(e); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - */ - public E floor(E e) { - return m.floorKey(e); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - */ - public E ceiling(E e) { - return m.ceilingKey(e); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if the specified element is null - */ - public E higher(E e) { - return m.higherKey(e); - } - - public E pollFirst() { - Map.Entry<E,Object> e = m.pollFirstEntry(); - return e == null? null : e.getKey(); - } - - public E pollLast() { - Map.Entry<E,Object> e = m.pollLastEntry(); - return e == null? null : e.getKey(); - } - - - /* ---------------- SortedSet operations -------------- */ - - - public Comparator<? super E> comparator() { - return m.comparator(); - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E first() { - return m.firstKey(); - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E last() { - return m.lastKey(); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code fromElement} or - * {@code toElement} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public NavigableSet<E> subSet(E fromElement, - boolean fromInclusive, - E toElement, - boolean toInclusive) { - return new ConcurrentSkipListSet<E> - (m.subMap(fromElement, fromInclusive, - toElement, toInclusive)); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code toElement} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public NavigableSet<E> headSet(E toElement, boolean inclusive) { - return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive)); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code fromElement} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { - return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive)); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code fromElement} or - * {@code toElement} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public NavigableSet<E> subSet(E fromElement, E toElement) { - return subSet(fromElement, true, toElement, false); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code toElement} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public NavigableSet<E> headSet(E toElement) { - return headSet(toElement, false); - } - - /** - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException if {@code fromElement} is null - * @throws IllegalArgumentException {@inheritDoc} - */ - public NavigableSet<E> tailSet(E fromElement) { - return tailSet(fromElement, true); - } - - /** - * Returns a reverse order view of the elements contained in this set. - * The descending set is backed by this set, so changes to the set are - * reflected in the descending set, and vice-versa. - * - * <p>The returned set has an ordering equivalent to - * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. - * The expression {@code s.descendingSet().descendingSet()} returns a - * view of {@code s} essentially equivalent to {@code s}. - * - * @return a reverse order view of this set - */ - public NavigableSet<E> descendingSet() { - return new ConcurrentSkipListSet(m.descendingMap()); - } - - // Support for resetting map in clone - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long mapOffset; - static { - try { - mapOffset = unsafe.objectFieldOffset - (ConcurrentSkipListSet.class.getDeclaredField("m")); - } catch (Exception ex) { throw new Error(ex); } - } - private void setMap(ConcurrentNavigableMap<E,Object> map) { - unsafe.putObjectVolatile(this, mapOffset, map); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CopyOnWriteArraySet.java b/libjava/classpath/external/jsr166/java/util/concurrent/CopyOnWriteArraySet.java deleted file mode 100644 index 063636b..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/CopyOnWriteArraySet.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain. Use, modify, and - * redistribute this code in any way without acknowledgement. - */ - -package java.util.concurrent; -import java.util.*; - -/** - * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList} - * for all of its operations. Thus, it shares the same basic properties: - * <ul> - * <li>It is best suited for applications in which set sizes generally - * stay small, read-only operations - * vastly outnumber mutative operations, and you need - * to prevent interference among threads during traversal. - * <li>It is thread-safe. - * <li>Mutative operations (<tt>add</tt>, <tt>set</tt>, <tt>remove</tt>, etc.) - * are expensive since they usually entail copying the entire underlying - * array. - * <li>Iterators do not support the mutative <tt>remove</tt> operation. - * <li>Traversal via iterators is fast and cannot encounter - * interference from other threads. Iterators rely on - * unchanging snapshots of the array at the time the iterators were - * constructed. - * </ul> - * - * <p> <b>Sample Usage.</b> The following code sketch uses a - * copy-on-write set to maintain a set of Handler objects that - * perform some action upon state updates. - * - * <pre> - * class Handler { void handle(); ... } - * - * class X { - * private final CopyOnWriteArraySet<Handler> handlers - * = new CopyOnWriteArraySet<Handler>(); - * public void addHandler(Handler h) { handlers.add(h); } - * - * private long internalState; - * private synchronized void changeState() { internalState = ...; } - * - * public void update() { - * changeState(); - * for (Handler handler : handlers) - * handler.handle(); - * } - * } - * </pre> - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @see CopyOnWriteArrayList - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ -public class CopyOnWriteArraySet<E> extends AbstractSet<E> - implements java.io.Serializable { - private static final long serialVersionUID = 5457747651344034263L; - - private final CopyOnWriteArrayList<E> al; - - /** - * Creates an empty set. - */ - public CopyOnWriteArraySet() { - al = new CopyOnWriteArrayList<E>(); - } - - /** - * Creates a set containing all of the elements of the specified - * collection. - * - * @param c the collection of elements to initially contain - * @throws NullPointerException if the specified collection is null - */ - public CopyOnWriteArraySet(Collection<? extends E> c) { - al = new CopyOnWriteArrayList<E>(); - al.addAllAbsent(c); - } - - /** - * Returns the number of elements in this set. - * - * @return the number of elements in this set - */ - public int size() { - return al.size(); - } - - /** - * Returns <tt>true</tt> if this set contains no elements. - * - * @return <tt>true</tt> if this set contains no elements - */ - public boolean isEmpty() { - return al.isEmpty(); - } - - /** - * Returns <tt>true</tt> if this set contains the specified element. - * More formally, returns <tt>true</tt> if and only if this set - * contains an element <tt>e</tt> such that - * <tt>(o==null ? e==null : o.equals(e))</tt>. - * - * @param o element whose presence in this set is to be tested - * @return <tt>true</tt> if this set contains the specified element - */ - public boolean contains(Object o) { - return al.contains(o); - } - - /** - * Returns an array containing all of the elements in this set. - * If this set makes any guarantees as to what order its elements - * are returned by its iterator, this method must return the - * elements in the same order. - * - * <p>The returned array will be "safe" in that no references to it - * are maintained by this set. (In other words, this method must - * allocate a new array even if this set is backed by an array). - * The caller is thus free to modify the returned array. - * - * <p>This method acts as bridge between array-based and collection-based - * APIs. - * - * @return an array containing all the elements in this set - */ - public Object[] toArray() { - return al.toArray(); - } - - /** - * Returns an array containing all of the elements in this set; the - * runtime type of the returned array is that of the specified array. - * If the set fits in the specified array, it is returned therein. - * Otherwise, a new array is allocated with the runtime type of the - * specified array and the size of this set. - * - * <p>If this set fits in the specified array with room to spare - * (i.e., the array has more elements than this set), the element in - * the array immediately following the end of the set is set to - * <tt>null</tt>. (This is useful in determining the length of this - * set <i>only</i> if the caller knows that this set does not contain - * any null elements.) - * - * <p>If this set makes any guarantees as to what order its elements - * are returned by its iterator, this method must return the elements - * in the same order. - * - * <p>Like the {@link #toArray()} method, this method acts as bridge between - * array-based and collection-based APIs. Further, this method allows - * precise control over the runtime type of the output array, and may, - * under certain circumstances, be used to save allocation costs. - * - * <p>Suppose <tt>x</tt> is a set known to contain only strings. - * The following code can be used to dump the set into a newly allocated - * array of <tt>String</tt>: - * - * <pre> - * String[] y = x.toArray(new String[0]);</pre> - * - * Note that <tt>toArray(new Object[0])</tt> is identical in function to - * <tt>toArray()</tt>. - * - * @param a the array into which the elements of this set are to be - * stored, if it is big enough; otherwise, a new array of the same - * runtime type is allocated for this purpose. - * @return an array containing all the elements in this set - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in this - * set - * @throws NullPointerException if the specified array is null - */ - public <T> T[] toArray(T[] a) { - return al.toArray(a); - } - - /** - * Removes all of the elements from this set. - * The set will be empty after this call returns. - */ - public void clear() { - al.clear(); - } - - /** - * Removes the specified element from this set if it is present. - * More formally, removes an element <tt>e</tt> such that - * <tt>(o==null ? e==null : o.equals(e))</tt>, - * if this set contains such an element. Returns <tt>true</tt> if - * this set contained the element (or equivalently, if this set - * changed as a result of the call). (This set will not contain the - * element once the call returns.) - * - * @param o object to be removed from this set, if present - * @return <tt>true</tt> if this set contained the specified element - */ - public boolean remove(Object o) { - return al.remove(o); - } - - /** - * Adds the specified element to this set if it is not already present. - * More formally, adds the specified element <tt>e</tt> to this set if - * the set contains no element <tt>e2</tt> such that - * <tt>(e==null ? e2==null : e.equals(e2))</tt>. - * If this set already contains the element, the call leaves the set - * unchanged and returns <tt>false</tt>. - * - * @param e element to be added to this set - * @return <tt>true</tt> if this set did not already contain the specified - * element - */ - public boolean add(E e) { - return al.addIfAbsent(e); - } - - /** - * Returns <tt>true</tt> if this set contains all of the elements of the - * specified collection. If the specified collection is also a set, this - * method returns <tt>true</tt> if it is a <i>subset</i> of this set. - * - * @param c collection to be checked for containment in this set - * @return <tt>true</tt> if this set contains all of the elements of the - * specified collection - * @throws NullPointerException if the specified collection is null - * @see #contains(Object) - */ - public boolean containsAll(Collection<?> c) { - return al.containsAll(c); - } - - /** - * Adds all of the elements in the specified collection to this set if - * they're not already present. If the specified collection is also a - * set, the <tt>addAll</tt> operation effectively modifies this set so - * that its value is the <i>union</i> of the two sets. The behavior of - * this operation is undefined if the specified collection is modified - * while the operation is in progress. - * - * @param c collection containing elements to be added to this set - * @return <tt>true</tt> if this set changed as a result of the call - * @throws NullPointerException if the specified collection is null - * @see #add(Object) - */ - public boolean addAll(Collection<? extends E> c) { - return al.addAllAbsent(c) > 0; - } - - /** - * Removes from this set all of its elements that are contained in the - * specified collection. If the specified collection is also a set, - * this operation effectively modifies this set so that its value is the - * <i>asymmetric set difference</i> of the two sets. - * - * @param c collection containing elements to be removed from this set - * @return <tt>true</tt> if this set changed as a result of the call - * @throws ClassCastException if the class of an element of this set - * is incompatible with the specified collection (optional) - * @throws NullPointerException if this set contains a null element and the - * specified collection does not permit null elements (optional), - * or if the specified collection is null - * @see #remove(Object) - */ - public boolean removeAll(Collection<?> c) { - return al.removeAll(c); - } - - /** - * Retains only the elements in this set that are contained in the - * specified collection. In other words, removes from this set all of - * its elements that are not contained in the specified collection. If - * the specified collection is also a set, this operation effectively - * modifies this set so that its value is the <i>intersection</i> of the - * two sets. - * - * @param c collection containing elements to be retained in this set - * @return <tt>true</tt> if this set changed as a result of the call - * @throws ClassCastException if the class of an element of this set - * is incompatible with the specified collection (optional) - * @throws NullPointerException if this set contains a null element and the - * specified collection does not permit null elements (optional), - * or if the specified collection is null - * @see #remove(Object) - */ - public boolean retainAll(Collection<?> c) { - return al.retainAll(c); - } - - /** - * Returns an iterator over the elements contained in this set - * in the order in which these elements were added. - * - * <p>The returned iterator provides a snapshot of the state of the set - * when the iterator was constructed. No synchronization is needed while - * traversing the iterator. The iterator does <em>NOT</em> support the - * <tt>remove</tt> method. - * - * @return an iterator over the elements in this set - */ - public Iterator<E> iterator() { - return al.iterator(); - } - - /** - * Compares the specified object with this set for equality. - * Returns {@code true} if the specified object is the same object - * as this object, or if it is also a {@link Set} and the elements - * returned by an {@linkplain List#iterator() iterator} over the - * specified set are the same as the elements returned by an - * iterator over this set. More formally, the two iterators are - * considered to return the same elements if they return the same - * number of elements and for every element {@code e1} returned by - * the iterator over the specified set, there is an element - * {@code e2} returned by the iterator over this set such that - * {@code (e1==null ? e2==null : e1.equals(e2))}. - * - * @param o object to be compared for equality with this set - * @return {@code true} if the specified object is equal to this set - */ - public boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof Set)) - return false; - Set<?> set = (Set<?>)(o); - Iterator<?> it = set.iterator(); - - // Uses O(n^2) algorithm that is only appropriate - // for small sets, which CopyOnWriteArraySets should be. - - // Use a single snapshot of underlying array - Object[] elements = al.getArray(); - int len = elements.length; - // Mark matched elements to avoid re-checking - boolean[] matched = new boolean[len]; - int k = 0; - outer: while (it.hasNext()) { - if (++k > len) - return false; - Object x = it.next(); - for (int i = 0; i < len; ++i) { - if (!matched[i] && eq(x, elements[i])) { - matched[i] = true; - continue outer; - } - } - return false; - } - return k == len; - } - - /** - * Test for equality, coping with nulls. - */ - private static boolean eq(Object o1, Object o2) { - return (o1 == null ? o2 == null : o1.equals(o2)); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CountDownLatch.java b/libjava/classpath/external/jsr166/java/util/concurrent/CountDownLatch.java deleted file mode 100644 index 016c1a7..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/CountDownLatch.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.locks.*; -import java.util.concurrent.atomic.*; - -/** - * A synchronization aid that allows one or more threads to wait until - * a set of operations being performed in other threads completes. - * - * <p>A {@code CountDownLatch} is initialized with a given <em>count</em>. - * The {@link #await await} methods block until the current count reaches - * zero due to invocations of the {@link #countDown} method, after which - * all waiting threads are released and any subsequent invocations of - * {@link #await await} return immediately. This is a one-shot phenomenon - * -- the count cannot be reset. If you need a version that resets the - * count, consider using a {@link CyclicBarrier}. - * - * <p>A {@code CountDownLatch} is a versatile synchronization tool - * and can be used for a number of purposes. A - * {@code CountDownLatch} initialized with a count of one serves as a - * simple on/off latch, or gate: all threads invoking {@link #await await} - * wait at the gate until it is opened by a thread invoking {@link - * #countDown}. A {@code CountDownLatch} initialized to <em>N</em> - * can be used to make one thread wait until <em>N</em> threads have - * completed some action, or some action has been completed N times. - * - * <p>A useful property of a {@code CountDownLatch} is that it - * doesn't require that threads calling {@code countDown} wait for - * the count to reach zero before proceeding, it simply prevents any - * thread from proceeding past an {@link #await await} until all - * threads could pass. - * - * <p><b>Sample usage:</b> Here is a pair of classes in which a group - * of worker threads use two countdown latches: - * <ul> - * <li>The first is a start signal that prevents any worker from proceeding - * until the driver is ready for them to proceed; - * <li>The second is a completion signal that allows the driver to wait - * until all workers have completed. - * </ul> - * - * <pre> - * class Driver { // ... - * void main() throws InterruptedException { - * CountDownLatch startSignal = new CountDownLatch(1); - * CountDownLatch doneSignal = new CountDownLatch(N); - * - * for (int i = 0; i < N; ++i) // create and start threads - * new Thread(new Worker(startSignal, doneSignal)).start(); - * - * doSomethingElse(); // don't let run yet - * startSignal.countDown(); // let all threads proceed - * doSomethingElse(); - * doneSignal.await(); // wait for all to finish - * } - * } - * - * class Worker implements Runnable { - * private final CountDownLatch startSignal; - * private final CountDownLatch doneSignal; - * Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { - * this.startSignal = startSignal; - * this.doneSignal = doneSignal; - * } - * public void run() { - * try { - * startSignal.await(); - * doWork(); - * doneSignal.countDown(); - * } catch (InterruptedException ex) {} // return; - * } - * - * void doWork() { ... } - * } - * - * </pre> - * - * <p>Another typical usage would be to divide a problem into N parts, - * describe each part with a Runnable that executes that portion and - * counts down on the latch, and queue all the Runnables to an - * Executor. When all sub-parts are complete, the coordinating thread - * will be able to pass through await. (When threads must repeatedly - * count down in this way, instead use a {@link CyclicBarrier}.) - * - * <pre> - * class Driver2 { // ... - * void main() throws InterruptedException { - * CountDownLatch doneSignal = new CountDownLatch(N); - * Executor e = ... - * - * for (int i = 0; i < N; ++i) // create and start threads - * e.execute(new WorkerRunnable(doneSignal, i)); - * - * doneSignal.await(); // wait for all to finish - * } - * } - * - * class WorkerRunnable implements Runnable { - * private final CountDownLatch doneSignal; - * private final int i; - * WorkerRunnable(CountDownLatch doneSignal, int i) { - * this.doneSignal = doneSignal; - * this.i = i; - * } - * public void run() { - * try { - * doWork(i); - * doneSignal.countDown(); - * } catch (InterruptedException ex) {} // return; - * } - * - * void doWork() { ... } - * } - * - * </pre> - * - * <p>Memory consistency effects: Actions in a thread prior to calling - * {@code countDown()} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * actions following a successful return from a corresponding - * {@code await()} in another thread. - * - * @since 1.5 - * @author Doug Lea - */ -public class CountDownLatch { - /** - * Synchronization control For CountDownLatch. - * Uses AQS state to represent count. - */ - private static final class Sync extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = 4982264981922014374L; - - Sync(int count) { - setState(count); - } - - int getCount() { - return getState(); - } - - public int tryAcquireShared(int acquires) { - return getState() == 0? 1 : -1; - } - - public boolean tryReleaseShared(int releases) { - // Decrement count; signal when transition to zero - for (;;) { - int c = getState(); - if (c == 0) - return false; - int nextc = c-1; - if (compareAndSetState(c, nextc)) - return nextc == 0; - } - } - } - - private final Sync sync; - - /** - * Constructs a {@code CountDownLatch} initialized with the given count. - * - * @param count the number of times {@link #countDown} must be invoked - * before threads can pass through {@link #await} - * @throws IllegalArgumentException if {@code count} is negative - */ - public CountDownLatch(int count) { - if (count < 0) throw new IllegalArgumentException("count < 0"); - this.sync = new Sync(count); - } - - /** - * Causes the current thread to wait until the latch has counted down to - * zero, unless the thread is {@linkplain Thread#interrupt interrupted}. - * - * <p>If the current count is zero then this method returns immediately. - * - * <p>If the current count is greater than zero then the current - * thread becomes disabled for thread scheduling purposes and lies - * dormant until one of two things happen: - * <ul> - * <li>The count reaches zero due to invocations of the - * {@link #countDown} method; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread. - * </ul> - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * @throws InterruptedException if the current thread is interrupted - * while waiting - */ - public void await() throws InterruptedException { - sync.acquireSharedInterruptibly(1); - } - - /** - * Causes the current thread to wait until the latch has counted down to - * zero, unless the thread is {@linkplain Thread#interrupt interrupted}, - * or the specified waiting time elapses. - * - * <p>If the current count is zero then this method returns immediately - * with the value {@code true}. - * - * <p>If the current count is greater than zero then the current - * thread becomes disabled for thread scheduling purposes and lies - * dormant until one of three things happen: - * <ul> - * <li>The count reaches zero due to invocations of the - * {@link #countDown} method; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * <li>The specified waiting time elapses. - * </ul> - * - * <p>If the count reaches zero then the method returns with the - * value {@code true}. - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p>If the specified waiting time elapses then the value {@code false} - * is returned. If the time is less than or equal to zero, the method - * will not wait at all. - * - * @param timeout the maximum time to wait - * @param unit the time unit of the {@code timeout} argument - * @return {@code true} if the count reached zero and {@code false} - * if the waiting time elapsed before the count reached zero - * @throws InterruptedException if the current thread is interrupted - * while waiting - */ - public boolean await(long timeout, TimeUnit unit) - throws InterruptedException { - return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); - } - - /** - * Decrements the count of the latch, releasing all waiting threads if - * the count reaches zero. - * - * <p>If the current count is greater than zero then it is decremented. - * If the new count is zero then all waiting threads are re-enabled for - * thread scheduling purposes. - * - * <p>If the current count equals zero then nothing happens. - */ - public void countDown() { - sync.releaseShared(1); - } - - /** - * Returns the current count. - * - * <p>This method is typically used for debugging and testing purposes. - * - * @return the current count - */ - public long getCount() { - return sync.getCount(); - } - - /** - * Returns a string identifying this latch, as well as its state. - * The state, in brackets, includes the String {@code "Count ="} - * followed by the current count. - * - * @return a string identifying this latch, as well as its state - */ - public String toString() { - return super.toString() + "[Count = " + sync.getCount() + "]"; - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CyclicBarrier.java b/libjava/classpath/external/jsr166/java/util/concurrent/CyclicBarrier.java deleted file mode 100644 index d5738c5..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/CyclicBarrier.java +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.locks.*; - -/** - * A synchronization aid that allows a set of threads to all wait for - * each other to reach a common barrier point. CyclicBarriers are - * useful in programs involving a fixed sized party of threads that - * must occasionally wait for each other. The barrier is called - * <em>cyclic</em> because it can be re-used after the waiting threads - * are released. - * - * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command - * that is run once per barrier point, after the last thread in the party - * arrives, but before any threads are released. - * This <em>barrier action</em> is useful - * for updating shared-state before any of the parties continue. - * - * <p><b>Sample usage:</b> Here is an example of - * using a barrier in a parallel decomposition design: - * <pre> - * class Solver { - * final int N; - * final float[][] data; - * final CyclicBarrier barrier; - * - * class Worker implements Runnable { - * int myRow; - * Worker(int row) { myRow = row; } - * public void run() { - * while (!done()) { - * processRow(myRow); - * - * try { - * barrier.await(); - * } catch (InterruptedException ex) { - * return; - * } catch (BrokenBarrierException ex) { - * return; - * } - * } - * } - * } - * - * public Solver(float[][] matrix) { - * data = matrix; - * N = matrix.length; - * barrier = new CyclicBarrier(N, - * new Runnable() { - * public void run() { - * mergeRows(...); - * } - * }); - * for (int i = 0; i < N; ++i) - * new Thread(new Worker(i)).start(); - * - * waitUntilDone(); - * } - * } - * </pre> - * Here, each worker thread processes a row of the matrix then waits at the - * barrier until all rows have been processed. When all rows are processed - * the supplied {@link Runnable} barrier action is executed and merges the - * rows. If the merger - * determines that a solution has been found then <tt>done()</tt> will return - * <tt>true</tt> and each worker will terminate. - * - * <p>If the barrier action does not rely on the parties being suspended when - * it is executed, then any of the threads in the party could execute that - * action when it is released. To facilitate this, each invocation of - * {@link #await} returns the arrival index of that thread at the barrier. - * You can then choose which thread should execute the barrier action, for - * example: - * <pre> if (barrier.await() == 0) { - * // log the completion of this iteration - * }</pre> - * - * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model - * for failed synchronization attempts: If a thread leaves a barrier - * point prematurely because of interruption, failure, or timeout, all - * other threads waiting at that barrier point will also leave - * abnormally via {@link BrokenBarrierException} (or - * {@link InterruptedException} if they too were interrupted at about - * the same time). - * - * <p>Memory consistency effects: Actions in a thread prior to calling - * {@code await()} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * actions that are part of the barrier action, which in turn - * <i>happen-before</i> actions following a successful return from the - * corresponding {@code await()} in other threads. - * - * @since 1.5 - * @see CountDownLatch - * - * @author Doug Lea - */ -public class CyclicBarrier { - /** - * Each use of the barrier is represented as a generation instance. - * The generation changes whenever the barrier is tripped, or - * is reset. There can be many generations associated with threads - * using the barrier - due to the non-deterministic way the lock - * may be allocated to waiting threads - but only one of these - * can be active at a time (the one to which <tt>count</tt> applies) - * and all the rest are either broken or tripped. - * There need not be an active generation if there has been a break - * but no subsequent reset. - */ - private static class Generation { - boolean broken = false; - } - - /** The lock for guarding barrier entry */ - private final ReentrantLock lock = new ReentrantLock(); - /** Condition to wait on until tripped */ - private final Condition trip = lock.newCondition(); - /** The number of parties */ - private final int parties; - /* The command to run when tripped */ - private final Runnable barrierCommand; - /** The current generation */ - private Generation generation = new Generation(); - - /** - * Number of parties still waiting. Counts down from parties to 0 - * on each generation. It is reset to parties on each new - * generation or when broken. - */ - private int count; - - /** - * Updates state on barrier trip and wakes up everyone. - * Called only while holding lock. - */ - private void nextGeneration() { - // signal completion of last generation - trip.signalAll(); - // set up next generation - count = parties; - generation = new Generation(); - } - - /** - * Sets current barrier generation as broken and wakes up everyone. - * Called only while holding lock. - */ - private void breakBarrier() { - generation.broken = true; - count = parties; - trip.signalAll(); - } - - /** - * Main barrier code, covering the various policies. - */ - private int dowait(boolean timed, long nanos) - throws InterruptedException, BrokenBarrierException, - TimeoutException { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - final Generation g = generation; - - if (g.broken) - throw new BrokenBarrierException(); - - if (Thread.interrupted()) { - breakBarrier(); - throw new InterruptedException(); - } - - int index = --count; - if (index == 0) { // tripped - boolean ranAction = false; - try { - final Runnable command = barrierCommand; - if (command != null) - command.run(); - ranAction = true; - nextGeneration(); - return 0; - } finally { - if (!ranAction) - breakBarrier(); - } - } - - // loop until tripped, broken, interrupted, or timed out - for (;;) { - try { - if (!timed) - trip.await(); - else if (nanos > 0L) - nanos = trip.awaitNanos(nanos); - } catch (InterruptedException ie) { - if (g == generation && ! g.broken) { - breakBarrier(); - throw ie; - } else { - // We're about to finish waiting even if we had not - // been interrupted, so this interrupt is deemed to - // "belong" to subsequent execution. - Thread.currentThread().interrupt(); - } - } - - if (g.broken) - throw new BrokenBarrierException(); - - if (g != generation) - return index; - - if (timed && nanos <= 0L) { - breakBarrier(); - throw new TimeoutException(); - } - } - } finally { - lock.unlock(); - } - } - - /** - * Creates a new <tt>CyclicBarrier</tt> that will trip when the - * given number of parties (threads) are waiting upon it, and which - * will execute the given barrier action when the barrier is tripped, - * performed by the last thread entering the barrier. - * - * @param parties the number of threads that must invoke {@link #await} - * before the barrier is tripped - * @param barrierAction the command to execute when the barrier is - * tripped, or {@code null} if there is no action - * @throws IllegalArgumentException if {@code parties} is less than 1 - */ - public CyclicBarrier(int parties, Runnable barrierAction) { - if (parties <= 0) throw new IllegalArgumentException(); - this.parties = parties; - this.count = parties; - this.barrierCommand = barrierAction; - } - - /** - * Creates a new <tt>CyclicBarrier</tt> that will trip when the - * given number of parties (threads) are waiting upon it, and - * does not perform a predefined action when the barrier is tripped. - * - * @param parties the number of threads that must invoke {@link #await} - * before the barrier is tripped - * @throws IllegalArgumentException if {@code parties} is less than 1 - */ - public CyclicBarrier(int parties) { - this(parties, null); - } - - /** - * Returns the number of parties required to trip this barrier. - * - * @return the number of parties required to trip this barrier - */ - public int getParties() { - return parties; - } - - /** - * Waits until all {@linkplain #getParties parties} have invoked - * <tt>await</tt> on this barrier. - * - * <p>If the current thread is not the last to arrive then it is - * disabled for thread scheduling purposes and lies dormant until - * one of the following things happens: - * <ul> - * <li>The last thread arrives; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * one of the other waiting threads; or - * <li>Some other thread times out while waiting for barrier; or - * <li>Some other thread invokes {@link #reset} on this barrier. - * </ul> - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p>If the barrier is {@link #reset} while any thread is waiting, - * or if the barrier {@linkplain #isBroken is broken} when - * <tt>await</tt> is invoked, or while any thread is waiting, then - * {@link BrokenBarrierException} is thrown. - * - * <p>If any thread is {@linkplain Thread#interrupt interrupted} while waiting, - * then all other waiting threads will throw - * {@link BrokenBarrierException} and the barrier is placed in the broken - * state. - * - * <p>If the current thread is the last thread to arrive, and a - * non-null barrier action was supplied in the constructor, then the - * current thread runs the action before allowing the other threads to - * continue. - * If an exception occurs during the barrier action then that exception - * will be propagated in the current thread and the barrier is placed in - * the broken state. - * - * @return the arrival index of the current thread, where index - * <tt>{@link #getParties()} - 1</tt> indicates the first - * to arrive and zero indicates the last to arrive - * @throws InterruptedException if the current thread was interrupted - * while waiting - * @throws BrokenBarrierException if <em>another</em> thread was - * interrupted or timed out while the current thread was - * waiting, or the barrier was reset, or the barrier was - * broken when {@code await} was called, or the barrier - * action (if present) failed due an exception. - */ - public int await() throws InterruptedException, BrokenBarrierException { - try { - return dowait(false, 0L); - } catch (TimeoutException toe) { - throw new Error(toe); // cannot happen; - } - } - - /** - * Waits until all {@linkplain #getParties parties} have invoked - * <tt>await</tt> on this barrier, or the specified waiting time elapses. - * - * <p>If the current thread is not the last to arrive then it is - * disabled for thread scheduling purposes and lies dormant until - * one of the following things happens: - * <ul> - * <li>The last thread arrives; or - * <li>The specified timeout elapses; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * one of the other waiting threads; or - * <li>Some other thread times out while waiting for barrier; or - * <li>Some other thread invokes {@link #reset} on this barrier. - * </ul> - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p>If the specified waiting time elapses then {@link TimeoutException} - * is thrown. If the time is less than or equal to zero, the - * method will not wait at all. - * - * <p>If the barrier is {@link #reset} while any thread is waiting, - * or if the barrier {@linkplain #isBroken is broken} when - * <tt>await</tt> is invoked, or while any thread is waiting, then - * {@link BrokenBarrierException} is thrown. - * - * <p>If any thread is {@linkplain Thread#interrupt interrupted} while - * waiting, then all other waiting threads will throw {@link - * BrokenBarrierException} and the barrier is placed in the broken - * state. - * - * <p>If the current thread is the last thread to arrive, and a - * non-null barrier action was supplied in the constructor, then the - * current thread runs the action before allowing the other threads to - * continue. - * If an exception occurs during the barrier action then that exception - * will be propagated in the current thread and the barrier is placed in - * the broken state. - * - * @param timeout the time to wait for the barrier - * @param unit the time unit of the timeout parameter - * @return the arrival index of the current thread, where index - * <tt>{@link #getParties()} - 1</tt> indicates the first - * to arrive and zero indicates the last to arrive - * @throws InterruptedException if the current thread was interrupted - * while waiting - * @throws TimeoutException if the specified timeout elapses - * @throws BrokenBarrierException if <em>another</em> thread was - * interrupted or timed out while the current thread was - * waiting, or the barrier was reset, or the barrier was broken - * when {@code await} was called, or the barrier action (if - * present) failed due an exception - */ - public int await(long timeout, TimeUnit unit) - throws InterruptedException, - BrokenBarrierException, - TimeoutException { - return dowait(true, unit.toNanos(timeout)); - } - - /** - * Queries if this barrier is in a broken state. - * - * @return {@code true} if one or more parties broke out of this - * barrier due to interruption or timeout since - * construction or the last reset, or a barrier action - * failed due to an exception; {@code false} otherwise. - */ - public boolean isBroken() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return generation.broken; - } finally { - lock.unlock(); - } - } - - /** - * Resets the barrier to its initial state. If any parties are - * currently waiting at the barrier, they will return with a - * {@link BrokenBarrierException}. Note that resets <em>after</em> - * a breakage has occurred for other reasons can be complicated to - * carry out; threads need to re-synchronize in some other way, - * and choose one to perform the reset. It may be preferable to - * instead create a new barrier for subsequent use. - */ - public void reset() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - breakBarrier(); // break the current generation - nextGeneration(); // start a new generation - } finally { - lock.unlock(); - } - } - - /** - * Returns the number of parties currently waiting at the barrier. - * This method is primarily useful for debugging and assertions. - * - * @return the number of parties currently blocked in {@link #await} - */ - public int getNumberWaiting() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return parties - count; - } finally { - lock.unlock(); - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/DelayQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/DelayQueue.java deleted file mode 100644 index 4ce7bc6..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/DelayQueue.java +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - - -package java.util.concurrent; -import java.util.concurrent.locks.*; -import java.util.*; - -/** - * An unbounded {@linkplain BlockingQueue blocking queue} of - * <tt>Delayed</tt> elements, in which an element can only be taken - * when its delay has expired. The <em>head</em> of the queue is that - * <tt>Delayed</tt> element whose delay expired furthest in the - * past. If no delay has expired there is no head and <tt>poll</tt> - * will return <tt>null</tt>. Expiration occurs when an element's - * <tt>getDelay(TimeUnit.NANOSECONDS)</tt> method returns a value less - * than or equal to zero. Even though unexpired elements cannot be - * removed using <tt>take</tt> or <tt>poll</tt>, they are otherwise - * treated as normal elements. For example, the <tt>size</tt> method - * returns the count of both expired and unexpired elements. - * This queue does not permit null elements. - * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ - -public class DelayQueue<E extends Delayed> extends AbstractQueue<E> - implements BlockingQueue<E> { - - private transient final ReentrantLock lock = new ReentrantLock(); - private transient final Condition available = lock.newCondition(); - private final PriorityQueue<E> q = new PriorityQueue<E>(); - - /** - * Creates a new <tt>DelayQueue</tt> that is initially empty. - */ - public DelayQueue() {} - - /** - * Creates a <tt>DelayQueue</tt> initially containing the elements of the - * given collection of {@link Delayed} instances. - * - * @param c the collection of elements to initially contain - * @throws NullPointerException if the specified collection or any - * of its elements are null - */ - public DelayQueue(Collection<? extends E> c) { - this.addAll(c); - } - - /** - * Inserts the specified element into this delay queue. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws NullPointerException if the specified element is null - */ - public boolean add(E e) { - return offer(e); - } - - /** - * Inserts the specified element into this delay queue. - * - * @param e the element to add - * @return <tt>true</tt> - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e) { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - E first = q.peek(); - q.offer(e); - if (first == null || e.compareTo(first) < 0) - available.signalAll(); - return true; - } finally { - lock.unlock(); - } - } - - /** - * Inserts the specified element into this delay queue. As the queue is - * unbounded this method will never block. - * - * @param e the element to add - * @throws NullPointerException {@inheritDoc} - */ - public void put(E e) { - offer(e); - } - - /** - * Inserts the specified element into this delay queue. As the queue is - * unbounded this method will never block. - * - * @param e the element to add - * @param timeout This parameter is ignored as the method never blocks - * @param unit This parameter is ignored as the method never blocks - * @return <tt>true</tt> - * @throws NullPointerException {@inheritDoc} - */ - public boolean offer(E e, long timeout, TimeUnit unit) { - return offer(e); - } - - /** - * Retrieves and removes the head of this queue, or returns <tt>null</tt> - * if this queue has no elements with an expired delay. - * - * @return the head of this queue, or <tt>null</tt> if this - * queue has no elements with an expired delay - */ - public E poll() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - E first = q.peek(); - if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) - return null; - else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); - return x; - } - } finally { - lock.unlock(); - } - } - - /** - * Retrieves and removes the head of this queue, waiting if necessary - * until an element with an expired delay is available on this queue. - * - * @return the head of this queue - * @throws InterruptedException {@inheritDoc} - */ - public E take() throws InterruptedException { - final ReentrantLock lock = this.lock; - lock.lockInterruptibly(); - try { - for (;;) { - E first = q.peek(); - if (first == null) { - available.await(); - } else { - long delay = first.getDelay(TimeUnit.NANOSECONDS); - if (delay > 0) { - long tl = available.awaitNanos(delay); - } else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); // wake up other takers - return x; - - } - } - } - } finally { - lock.unlock(); - } - } - - /** - * Retrieves and removes the head of this queue, waiting if necessary - * until an element with an expired delay is available on this queue, - * or the specified wait time expires. - * - * @return the head of this queue, or <tt>null</tt> if the - * specified waiting time elapses before an element with - * an expired delay becomes available - * @throws InterruptedException {@inheritDoc} - */ - public E poll(long timeout, TimeUnit unit) throws InterruptedException { - long nanos = unit.toNanos(timeout); - final ReentrantLock lock = this.lock; - lock.lockInterruptibly(); - try { - for (;;) { - E first = q.peek(); - if (first == null) { - if (nanos <= 0) - return null; - else - nanos = available.awaitNanos(nanos); - } else { - long delay = first.getDelay(TimeUnit.NANOSECONDS); - if (delay > 0) { - if (nanos <= 0) - return null; - if (delay > nanos) - delay = nanos; - long timeLeft = available.awaitNanos(delay); - nanos -= delay - timeLeft; - } else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); - return x; - } - } - } - } finally { - lock.unlock(); - } - } - - /** - * Retrieves, but does not remove, the head of this queue, or - * returns <tt>null</tt> if this queue is empty. Unlike - * <tt>poll</tt>, if no expired elements are available in the queue, - * this method returns the element that will expire next, - * if one exists. - * - * @return the head of this queue, or <tt>null</tt> if this - * queue is empty. - */ - public E peek() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.peek(); - } finally { - lock.unlock(); - } - } - - public int size() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.size(); - } finally { - lock.unlock(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - final ReentrantLock lock = this.lock; - lock.lock(); - try { - int n = 0; - for (;;) { - E first = q.peek(); - if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) - break; - c.add(q.poll()); - ++n; - } - if (n > 0) - available.signalAll(); - return n; - } finally { - lock.unlock(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c, int maxElements) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - if (maxElements <= 0) - return 0; - final ReentrantLock lock = this.lock; - lock.lock(); - try { - int n = 0; - while (n < maxElements) { - E first = q.peek(); - if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) - break; - c.add(q.poll()); - ++n; - } - if (n > 0) - available.signalAll(); - return n; - } finally { - lock.unlock(); - } - } - - /** - * Atomically removes all of the elements from this delay queue. - * The queue will be empty after this call returns. - * Elements with an unexpired delay are not waited for; they are - * simply discarded from the queue. - */ - public void clear() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - q.clear(); - } finally { - lock.unlock(); - } - } - - /** - * Always returns <tt>Integer.MAX_VALUE</tt> because - * a <tt>DelayQueue</tt> is not capacity constrained. - * - * @return <tt>Integer.MAX_VALUE</tt> - */ - public int remainingCapacity() { - return Integer.MAX_VALUE; - } - - /** - * Returns an array containing all of the elements in this queue. - * The returned array elements are in no particular order. - * - * <p>The returned array will be "safe" in that no references to it are - * maintained by this queue. (In other words, this method must allocate - * a new array). The caller is thus free to modify the returned array. - * - * <p>This method acts as bridge between array-based and collection-based - * APIs. - * - * @return an array containing all of the elements in this queue - */ - public Object[] toArray() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.toArray(); - } finally { - lock.unlock(); - } - } - - /** - * Returns an array containing all of the elements in this queue; the - * runtime type of the returned array is that of the specified array. - * The returned array elements are in no particular order. - * If the queue fits in the specified array, it is returned therein. - * Otherwise, a new array is allocated with the runtime type of the - * specified array and the size of this queue. - * - * <p>If this queue fits in the specified array with room to spare - * (i.e., the array has more elements than this queue), the element in - * the array immediately following the end of the queue is set to - * <tt>null</tt>. - * - * <p>Like the {@link #toArray()} method, this method acts as bridge between - * array-based and collection-based APIs. Further, this method allows - * precise control over the runtime type of the output array, and may, - * under certain circumstances, be used to save allocation costs. - * - * <p>The following code can be used to dump a delay queue into a newly - * allocated array of <tt>Delayed</tt>: - * - * <pre> - * Delayed[] a = q.toArray(new Delayed[0]);</pre> - * - * Note that <tt>toArray(new Object[0])</tt> is identical in function to - * <tt>toArray()</tt>. - * - * @param a the array into which the elements of the queue are to - * be stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose - * @return an array containing all of the elements in this queue - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in - * this queue - * @throws NullPointerException if the specified array is null - */ - public <T> T[] toArray(T[] a) { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.toArray(a); - } finally { - lock.unlock(); - } - } - - /** - * Removes a single instance of the specified element from this - * queue, if it is present, whether or not it has expired. - */ - public boolean remove(Object o) { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.remove(o); - } finally { - lock.unlock(); - } - } - - /** - * Returns an iterator over all the elements (both expired and - * unexpired) in this queue. The iterator does not return the - * elements in any particular order. The returned - * <tt>Iterator</tt> is a "weakly consistent" iterator that will - * never throw {@link 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. - * - * @return an iterator over the elements in this queue - */ - public Iterator<E> iterator() { - return new Itr(toArray()); - } - - /** - * Snapshot iterator that works off copy of underlying q array. - */ - private class Itr implements Iterator<E> { - final Object[] array; // Array of all elements - int cursor; // index of next element to return; - int lastRet; // index of last element, or -1 if no such - - Itr(Object[] array) { - lastRet = -1; - this.array = array; - } - - public boolean hasNext() { - return cursor < array.length; - } - - public E next() { - if (cursor >= array.length) - throw new NoSuchElementException(); - lastRet = cursor; - return (E)array[cursor++]; - } - - public void remove() { - if (lastRet < 0) - throw new IllegalStateException(); - Object x = array[lastRet]; - lastRet = -1; - // Traverse underlying queue to find == element, - // not just a .equals element. - lock.lock(); - try { - for (Iterator it = q.iterator(); it.hasNext(); ) { - if (it.next() == x) { - it.remove(); - return; - } - } - } finally { - lock.unlock(); - } - } - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Delayed.java b/libjava/classpath/external/jsr166/java/util/concurrent/Delayed.java deleted file mode 100644 index b1ff4ee..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/Delayed.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -import java.util.*; - -/** - * A mix-in style interface for marking objects that should be - * acted upon after a given delay. - * - * <p>An implementation of this interface must define a - * <tt>compareTo</tt> method that provides an ordering consistent with - * its <tt>getDelay</tt> method. - * - * @since 1.5 - * @author Doug Lea - */ -public interface Delayed extends Comparable<Delayed> { - - /** - * Returns the remaining delay associated with this object, in the - * given time unit. - * - * @param unit the time unit - * @return the remaining delay; zero or negative values indicate - * that the delay has already elapsed - */ - long getDelay(TimeUnit unit); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Exchanger.java b/libjava/classpath/external/jsr166/java/util/concurrent/Exchanger.java deleted file mode 100644 index fb917f4..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/Exchanger.java +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Written by Doug Lea, Bill Scherer, and Michael Scott with - * assistance from members of JCP JSR-166 Expert Group and released to - * the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.atomic.*; -import java.util.concurrent.locks.LockSupport; - -/** - * A synchronization point at which threads can pair and swap elements - * within pairs. Each thread presents some object on entry to the - * {@link #exchange exchange} method, matches with a partner thread, - * and receives its partner's object on return. An Exchanger may be - * viewed as a bidirectional form of a {@link SynchronousQueue}. - * Exchangers may be useful in applications such as genetic algorithms - * and pipeline designs. - * - * <p><b>Sample Usage:</b> - * Here are the highlights of a class that uses an {@code Exchanger} - * to swap buffers between threads so that the thread filling the - * buffer gets a freshly emptied one when it needs it, handing off the - * filled one to the thread emptying the buffer. - * <pre>{@code - * class FillAndEmpty { - * Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>(); - * DataBuffer initialEmptyBuffer = ... a made-up type - * DataBuffer initialFullBuffer = ... - * - * class FillingLoop implements Runnable { - * public void run() { - * DataBuffer currentBuffer = initialEmptyBuffer; - * try { - * while (currentBuffer != null) { - * addToBuffer(currentBuffer); - * if (currentBuffer.isFull()) - * currentBuffer = exchanger.exchange(currentBuffer); - * } - * } catch (InterruptedException ex) { ... handle ... } - * } - * } - * - * class EmptyingLoop implements Runnable { - * public void run() { - * DataBuffer currentBuffer = initialFullBuffer; - * try { - * while (currentBuffer != null) { - * takeFromBuffer(currentBuffer); - * if (currentBuffer.isEmpty()) - * currentBuffer = exchanger.exchange(currentBuffer); - * } - * } catch (InterruptedException ex) { ... handle ...} - * } - * } - * - * void start() { - * new Thread(new FillingLoop()).start(); - * new Thread(new EmptyingLoop()).start(); - * } - * } - * }</pre> - * - * <p>Memory consistency effects: For each pair of threads that - * successfully exchange objects via an {@code Exchanger}, actions - * prior to the {@code exchange()} in each thread - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * those subsequent to a return from the corresponding {@code exchange()} - * in the other thread. - * - * @since 1.5 - * @author Doug Lea and Bill Scherer and Michael Scott - * @param <V> The type of objects that may be exchanged - */ -public class Exchanger<V> { - /* - * Algorithm Description: - * - * The basic idea is to maintain a "slot", which is a reference to - * a Node containing both an Item to offer and a "hole" waiting to - * get filled in. If an incoming "occupying" thread sees that the - * slot is null, it CAS'es (compareAndSets) a Node there and waits - * for another to invoke exchange. That second "fulfilling" thread - * sees that the slot is non-null, and so CASes it back to null, - * also exchanging items by CASing the hole, plus waking up the - * occupying thread if it is blocked. In each case CAS'es may - * fail because a slot at first appears non-null but is null upon - * CAS, or vice-versa. So threads may need to retry these - * actions. - * - * This simple approach works great when there are only a few - * threads using an Exchanger, but performance rapidly - * deteriorates due to CAS contention on the single slot when - * there are lots of threads using an exchanger. So instead we use - * an "arena"; basically a kind of hash table with a dynamically - * varying number of slots, any one of which can be used by - * threads performing an exchange. Incoming threads pick slots - * based on a hash of their Thread ids. If an incoming thread - * fails to CAS in its chosen slot, it picks an alternative slot - * instead. And similarly from there. If a thread successfully - * CASes into a slot but no other thread arrives, it tries - * another, heading toward the zero slot, which always exists even - * if the table shrinks. The particular mechanics controlling this - * are as follows: - * - * Waiting: Slot zero is special in that it is the only slot that - * exists when there is no contention. A thread occupying slot - * zero will block if no thread fulfills it after a short spin. - * In other cases, occupying threads eventually give up and try - * another slot. Waiting threads spin for a while (a period that - * should be a little less than a typical context-switch time) - * before either blocking (if slot zero) or giving up (if other - * slots) and restarting. There is no reason for threads to block - * unless there are unlikely to be any other threads present. - * Occupants are mainly avoiding memory contention so sit there - * quietly polling for a shorter period than it would take to - * block and then unblock them. Non-slot-zero waits that elapse - * because of lack of other threads waste around one extra - * context-switch time per try, which is still on average much - * faster than alternative approaches. - * - * Sizing: Usually, using only a few slots suffices to reduce - * contention. Especially with small numbers of threads, using - * too many slots can lead to just as poor performance as using - * too few of them, and there's not much room for error. The - * variable "max" maintains the number of slots actually in - * use. It is increased when a thread sees too many CAS - * failures. (This is analogous to resizing a regular hash table - * based on a target load factor, except here, growth steps are - * just one-by-one rather than proportional.) Growth requires - * contention failures in each of three tried slots. Requiring - * multiple failures for expansion copes with the fact that some - * failed CASes are not due to contention but instead to simple - * races between two threads or thread pre-emptions occurring - * between reading and CASing. Also, very transient peak - * contention can be much higher than the average sustainable - * levels. The max limit is decreased on average 50% of the times - * that a non-slot-zero wait elapses without being fulfilled. - * Threads experiencing elapsed waits move closer to zero, so - * eventually find existing (or future) threads even if the table - * has been shrunk due to inactivity. The chosen mechanics and - * thresholds for growing and shrinking are intrinsically - * entangled with indexing and hashing inside the exchange code, - * and can't be nicely abstracted out. - * - * Hashing: Each thread picks its initial slot to use in accord - * with a simple hashcode. The sequence is the same on each - * encounter by any given thread, but effectively random across - * threads. Using arenas encounters the classic cost vs quality - * tradeoffs of all hash tables. Here, we use a one-step FNV-1a - * hash code based on the current thread's Thread.getId(), along - * with a cheap approximation to a mod operation to select an - * index. The downside of optimizing index selection in this way - * is that the code is hardwired to use a maximum table size of - * 32. But this value more than suffices for known platforms and - * applications. - * - * Probing: On sensed contention of a selected slot, we probe - * sequentially through the table, analogously to linear probing - * after collision in a hash table. (We move circularly, in - * reverse order, to mesh best with table growth and shrinkage - * rules.) Except that to minimize the effects of false-alarms - * and cache thrashing, we try the first selected slot twice - * before moving. - * - * Padding: Even with contention management, slots are heavily - * contended, so use cache-padding to avoid poor memory - * performance. Because of this, slots are lazily constructed - * only when used, to avoid wasting this space unnecessarily. - * While isolation of locations is not much of an issue at first - * in an application, as time goes on and garbage-collectors - * perform compaction, slots are very likely to be moved adjacent - * to each other, which can cause much thrashing of cache lines on - * MPs unless padding is employed. - * - * This is an improvement of the algorithm described in the paper - * "A Scalable Elimination-based Exchange Channel" by William - * Scherer, Doug Lea, and Michael Scott in Proceedings of SCOOL05 - * workshop. Available at: http://hdl.handle.net/1802/2104 - */ - - /** The number of CPUs, for sizing and spin control */ - private static final int NCPU = Runtime.getRuntime().availableProcessors(); - - /** - * The capacity of the arena. Set to a value that provides more - * than enough space to handle contention. On small machines - * most slots won't be used, but it is still not wasted because - * the extra space provides some machine-level address padding - * to minimize interference with heavily CAS'ed Slot locations. - * And on very large machines, performance eventually becomes - * bounded by memory bandwidth, not numbers of threads/CPUs. - * This constant cannot be changed without also modifying - * indexing and hashing algorithms. - */ - private static final int CAPACITY = 32; - - /** - * The value of "max" that will hold all threads without - * contention. When this value is less than CAPACITY, some - * otherwise wasted expansion can be avoided. - */ - private static final int FULL = - Math.max(0, Math.min(CAPACITY, NCPU / 2) - 1); - - /** - * The number of times to spin (doing nothing except polling a - * memory location) before blocking or giving up while waiting to - * be fulfilled. Should be zero on uniprocessors. On - * multiprocessors, this value should be large enough so that two - * threads exchanging items as fast as possible block only when - * one of them is stalled (due to GC or preemption), but not much - * longer, to avoid wasting CPU resources. Seen differently, this - * value is a little over half the number of cycles of an average - * context switch time on most systems. The value here is - * approximately the average of those across a range of tested - * systems. - */ - private static final int SPINS = (NCPU == 1) ? 0 : 2000; - - /** - * The number of times to spin before blocking in timed waits. - * Timed waits spin more slowly because checking the time takes - * time. The best value relies mainly on the relative rate of - * System.nanoTime vs memory accesses. The value is empirically - * derived to work well across a variety of systems. - */ - private static final int TIMED_SPINS = SPINS / 20; - - /** - * Sentinel item representing cancellation of a wait due to - * interruption, timeout, or elapsed spin-waits. This value is - * placed in holes on cancellation, and used as a return value - * from waiting methods to indicate failure to set or get hole. - */ - private static final Object CANCEL = new Object(); - - /** - * Value representing null arguments/returns from public - * methods. This disambiguates from internal requirement that - * holes start out as null to mean they are not yet set. - */ - private static final Object NULL_ITEM = new Object(); - - /** - * Nodes hold partially exchanged data. This class - * opportunistically subclasses AtomicReference to represent the - * hole. So get() returns hole, and compareAndSet CAS'es value - * into hole. This class cannot be parameterized as "V" because - * of the use of non-V CANCEL sentinels. - */ - private static final class Node extends AtomicReference<Object> { - /** The element offered by the Thread creating this node. */ - public final Object item; - - /** The Thread waiting to be signalled; null until waiting. */ - public volatile Thread waiter; - - /** - * Creates node with given item and empty hole. - * @param item the item - */ - public Node(Object item) { - this.item = item; - } - } - - /** - * A Slot is an AtomicReference with heuristic padding to lessen - * cache effects of this heavily CAS'ed location. While the - * padding adds noticeable space, all slots are created only on - * demand, and there will be more than one of them only when it - * would improve throughput more than enough to outweigh using - * extra space. - */ - private static final class Slot extends AtomicReference<Object> { - // Improve likelihood of isolation on <= 64 byte cache lines - long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe; - } - - /** - * Slot array. Elements are lazily initialized when needed. - * Declared volatile to enable double-checked lazy construction. - */ - private volatile Slot[] arena = new Slot[CAPACITY]; - - /** - * The maximum slot index being used. The value sometimes - * increases when a thread experiences too many CAS contentions, - * and sometimes decreases when a spin-wait elapses. Changes - * are performed only via compareAndSet, to avoid stale values - * when a thread happens to stall right before setting. - */ - private final AtomicInteger max = new AtomicInteger(); - - /** - * Main exchange function, handling the different policy variants. - * Uses Object, not "V" as argument and return value to simplify - * handling of sentinel values. Callers from public methods decode - * and cast accordingly. - * - * @param item the (non-null) item to exchange - * @param timed true if the wait is timed - * @param nanos if timed, the maximum wait time - * @return the other thread's item, or CANCEL if interrupted or timed out - */ - private Object doExchange(Object item, boolean timed, long nanos) { - Node me = new Node(item); // Create in case occupying - int index = hashIndex(); // Index of current slot - int fails = 0; // Number of CAS failures - - for (;;) { - Object y; // Contents of current slot - Slot slot = arena[index]; - if (slot == null) // Lazily initialize slots - createSlot(index); // Continue loop to reread - else if ((y = slot.get()) != null && // Try to fulfill - slot.compareAndSet(y, null)) { - Node you = (Node)y; // Transfer item - if (you.compareAndSet(null, item)) { - LockSupport.unpark(you.waiter); - return you.item; - } // Else cancelled; continue - } - else if (y == null && // Try to occupy - slot.compareAndSet(null, me)) { - if (index == 0) // Blocking wait for slot 0 - return timed? awaitNanos(me, slot, nanos): await(me, slot); - Object v = spinWait(me, slot); // Spin wait for non-0 - if (v != CANCEL) - return v; - me = new Node(item); // Throw away cancelled node - int m = max.get(); - if (m > (index >>>= 1)) // Decrease index - max.compareAndSet(m, m - 1); // Maybe shrink table - } - else if (++fails > 1) { // Allow 2 fails on 1st slot - int m = max.get(); - if (fails > 3 && m < FULL && max.compareAndSet(m, m + 1)) - index = m + 1; // Grow on 3rd failed slot - else if (--index < 0) - index = m; // Circularly traverse - } - } - } - - /** - * Returns a hash index for the current thread. Uses a one-step - * FNV-1a hash code (http://www.isthe.com/chongo/tech/comp/fnv/) - * based on the current thread's Thread.getId(). These hash codes - * have more uniform distribution properties with respect to small - * moduli (here 1-31) than do other simple hashing functions. - * - * <p>To return an index between 0 and max, we use a cheap - * approximation to a mod operation, that also corrects for bias - * due to non-power-of-2 remaindering (see {@link - * java.util.Random#nextInt}). Bits of the hashcode are masked - * with "nbits", the ceiling power of two of table size (looked up - * in a table packed into three ints). If too large, this is - * retried after rotating the hash by nbits bits, while forcing new - * top bit to 0, which guarantees eventual termination (although - * with a non-random-bias). This requires an average of less than - * 2 tries for all table sizes, and has a maximum 2% difference - * from perfectly uniform slot probabilities when applied to all - * possible hash codes for sizes less than 32. - * - * @return a per-thread-random index, 0 <= index < max - */ - private final int hashIndex() { - long id = Thread.currentThread().getId(); - int hash = (((int)(id ^ (id >>> 32))) ^ 0x811c9dc5) * 0x01000193; - - int m = max.get(); - int nbits = (((0xfffffc00 >> m) & 4) | // Compute ceil(log2(m+1)) - ((0x000001f8 >>> m) & 2) | // The constants hold - ((0xffff00f2 >>> m) & 1)); // a lookup table - int index; - while ((index = hash & ((1 << nbits) - 1)) > m) // May retry on - hash = (hash >>> nbits) | (hash << (33 - nbits)); // non-power-2 m - return index; - } - - /** - * Creates a new slot at given index. Called only when the slot - * appears to be null. Relies on double-check using builtin - * locks, since they rarely contend. This in turn relies on the - * arena array being declared volatile. - * - * @param index the index to add slot at - */ - private void createSlot(int index) { - // Create slot outside of lock to narrow sync region - Slot newSlot = new Slot(); - Slot[] a = arena; - synchronized (a) { - if (a[index] == null) - a[index] = newSlot; - } - } - - /** - * Tries to cancel a wait for the given node waiting in the given - * slot, if so, helping clear the node from its slot to avoid - * garbage retention. - * - * @param node the waiting node - * @param the slot it is waiting in - * @return true if successfully cancelled - */ - private static boolean tryCancel(Node node, Slot slot) { - if (!node.compareAndSet(null, CANCEL)) - return false; - if (slot.get() == node) // pre-check to minimize contention - slot.compareAndSet(node, null); - return true; - } - - // Three forms of waiting. Each just different enough not to merge - // code with others. - - /** - * Spin-waits for hole for a non-0 slot. Fails if spin elapses - * before hole filled. Does not check interrupt, relying on check - * in public exchange method to abort if interrupted on entry. - * - * @param node the waiting node - * @return on success, the hole; on failure, CANCEL - */ - private static Object spinWait(Node node, Slot slot) { - int spins = SPINS; - for (;;) { - Object v = node.get(); - if (v != null) - return v; - else if (spins > 0) - --spins; - else - tryCancel(node, slot); - } - } - - /** - * Waits for (by spinning and/or blocking) and gets the hole - * filled in by another thread. Fails if interrupted before - * hole filled. - * - * When a node/thread is about to block, it sets its waiter field - * and then rechecks state at least one more time before actually - * parking, thus covering race vs fulfiller noticing that waiter - * is non-null so should be woken. - * - * Thread interruption status is checked only surrounding calls to - * park. The caller is assumed to have checked interrupt status - * on entry. - * - * @param node the waiting node - * @return on success, the hole; on failure, CANCEL - */ - private static Object await(Node node, Slot slot) { - Thread w = Thread.currentThread(); - int spins = SPINS; - for (;;) { - Object v = node.get(); - if (v != null) - return v; - else if (spins > 0) // Spin-wait phase - --spins; - else if (node.waiter == null) // Set up to block next - node.waiter = w; - else if (w.isInterrupted()) // Abort on interrupt - tryCancel(node, slot); - else // Block - LockSupport.park(node); - } - } - - /** - * Waits for (at index 0) and gets the hole filled in by another - * thread. Fails if timed out or interrupted before hole filled. - * Same basic logic as untimed version, but a bit messier. - * - * @param node the waiting node - * @param nanos the wait time - * @return on success, the hole; on failure, CANCEL - */ - private Object awaitNanos(Node node, Slot slot, long nanos) { - int spins = TIMED_SPINS; - long lastTime = 0; - Thread w = null; - for (;;) { - Object v = node.get(); - if (v != null) - return v; - long now = System.nanoTime(); - if (w == null) - w = Thread.currentThread(); - else - nanos -= now - lastTime; - lastTime = now; - if (nanos > 0) { - if (spins > 0) - --spins; - else if (node.waiter == null) - node.waiter = w; - else if (w.isInterrupted()) - tryCancel(node, slot); - else - LockSupport.parkNanos(node, nanos); - } - else if (tryCancel(node, slot) && !w.isInterrupted()) - return scanOnTimeout(node); - } - } - - /** - * Sweeps through arena checking for any waiting threads. Called - * only upon return from timeout while waiting in slot 0. When a - * thread gives up on a timed wait, it is possible that a - * previously-entered thread is still waiting in some other - * slot. So we scan to check for any. This is almost always - * overkill, but decreases the likelihood of timeouts when there - * are other threads present to far less than that in lock-based - * exchangers in which earlier-arriving threads may still be - * waiting on entry locks. - * - * @param node the waiting node - * @return another thread's item, or CANCEL - */ - private Object scanOnTimeout(Node node) { - Object y; - for (int j = arena.length - 1; j >= 0; --j) { - Slot slot = arena[j]; - if (slot != null) { - while ((y = slot.get()) != null) { - if (slot.compareAndSet(y, null)) { - Node you = (Node)y; - if (you.compareAndSet(null, node.item)) { - LockSupport.unpark(you.waiter); - return you.item; - } - } - } - } - } - return CANCEL; - } - - /** - * Creates a new Exchanger. - */ - public Exchanger() { - } - - /** - * Waits for another thread to arrive at this exchange point (unless - * the current thread is {@linkplain Thread#interrupt interrupted}), - * and then transfers the given object to it, receiving its object - * in return. - * - * <p>If another thread is already waiting at the exchange point then - * it is resumed for thread scheduling purposes and receives the object - * passed in by the current thread. The current thread returns immediately, - * receiving the object passed to the exchange by that other thread. - * - * <p>If no other thread is already waiting at the exchange then the - * current thread is disabled for thread scheduling purposes and lies - * dormant until one of two things happens: - * <ul> - * <li>Some other thread enters the exchange; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current - * thread. - * </ul> - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * for the exchange, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * @param x the object to exchange - * @return the object provided by the other thread - * @throws InterruptedException if the current thread was - * interrupted while waiting - */ - public V exchange(V x) throws InterruptedException { - if (!Thread.interrupted()) { - Object v = doExchange(x == null? NULL_ITEM : x, false, 0); - if (v == NULL_ITEM) - return null; - if (v != CANCEL) - return (V)v; - Thread.interrupted(); // Clear interrupt status on IE throw - } - throw new InterruptedException(); - } - - /** - * Waits for another thread to arrive at this exchange point (unless - * the current thread is {@linkplain Thread#interrupt interrupted} or - * the specified waiting time elapses), and then transfers the given - * object to it, receiving its object in return. - * - * <p>If another thread is already waiting at the exchange point then - * it is resumed for thread scheduling purposes and receives the object - * passed in by the current thread. The current thread returns immediately, - * receiving the object passed to the exchange by that other thread. - * - * <p>If no other thread is already waiting at the exchange then the - * current thread is disabled for thread scheduling purposes and lies - * dormant until one of three things happens: - * <ul> - * <li>Some other thread enters the exchange; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * <li>The specified waiting time elapses. - * </ul> - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * for the exchange, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p>If the specified waiting time elapses then {@link - * TimeoutException} is thrown. If the time is less than or equal - * to zero, the method will not wait at all. - * - * @param x the object to exchange - * @param timeout the maximum time to wait - * @param unit the time unit of the <tt>timeout</tt> argument - * @return the object provided by the other thread - * @throws InterruptedException if the current thread was - * interrupted while waiting - * @throws TimeoutException if the specified waiting time elapses - * before another thread enters the exchange - */ - public V exchange(V x, long timeout, TimeUnit unit) - throws InterruptedException, TimeoutException { - if (!Thread.interrupted()) { - Object v = doExchange(x == null? NULL_ITEM : x, - true, unit.toNanos(timeout)); - if (v == NULL_ITEM) - return null; - if (v != CANCEL) - return (V)v; - if (!Thread.interrupted()) - throw new TimeoutException(); - } - throw new InterruptedException(); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutionException.java b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutionException.java deleted file mode 100644 index bc561e5..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutionException.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * Exception thrown when attempting to retrieve the result of a task - * that aborted by throwing an exception. This exception can be - * inspected using the {@link #getCause()} method. - * - * @see Future - * @since 1.5 - * @author Doug Lea - */ -public class ExecutionException extends Exception { - private static final long serialVersionUID = 7830266012832686185L; - - /** - * Constructs an <tt>ExecutionException</tt> with no detail message. - * The cause is not initialized, and may subsequently be - * initialized by a call to {@link #initCause(Throwable) initCause}. - */ - protected ExecutionException() { } - - /** - * Constructs an <tt>ExecutionException</tt> with the specified detail - * message. The cause is not initialized, and may subsequently be - * initialized by a call to {@link #initCause(Throwable) initCause}. - * - * @param message the detail message - */ - protected ExecutionException(String message) { - super(message); - } - - /** - * Constructs an <tt>ExecutionException</tt> with the specified detail - * message and cause. - * - * @param message the detail message - * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method) - */ - public ExecutionException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs an <tt>ExecutionException</tt> with the specified cause. - * The detail message is set to: - * <pre> - * (cause == null ? null : cause.toString())</pre> - * (which typically contains the class and detail message of - * <tt>cause</tt>). - * - * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method) - */ - public ExecutionException(Throwable cause) { - super(cause); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Executor.java b/libjava/classpath/external/jsr166/java/util/concurrent/Executor.java deleted file mode 100644 index a61e921..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/Executor.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * An object that executes submitted {@link Runnable} tasks. This - * interface provides a way of decoupling task submission from the - * mechanics of how each task will be run, including details of thread - * use, scheduling, etc. An <tt>Executor</tt> is normally used - * instead of explicitly creating threads. For example, rather than - * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each - * of a set of tasks, you might use: - * - * <pre> - * Executor executor = <em>anExecutor</em>; - * executor.execute(new RunnableTask1()); - * executor.execute(new RunnableTask2()); - * ... - * </pre> - * - * However, the <tt>Executor</tt> interface does not strictly - * require that execution be asynchronous. In the simplest case, an - * executor can run the submitted task immediately in the caller's - * thread: - * - * <pre> - * class DirectExecutor implements Executor { - * public void execute(Runnable r) { - * r.run(); - * } - * }</pre> - * - * More typically, tasks are executed in some thread other - * than the caller's thread. The executor below spawns a new thread - * for each task. - * - * <pre> - * class ThreadPerTaskExecutor implements Executor { - * public void execute(Runnable r) { - * new Thread(r).start(); - * } - * }</pre> - * - * Many <tt>Executor</tt> implementations impose some sort of - * limitation on how and when tasks are scheduled. The executor below - * serializes the submission of tasks to a second executor, - * illustrating a composite executor. - * - * <pre> - * class SerialExecutor implements Executor { - * final Queue<Runnable> tasks = new ArrayDeque<Runnable>(); - * final Executor executor; - * Runnable active; - * - * SerialExecutor(Executor executor) { - * this.executor = executor; - * } - * - * public synchronized void execute(final Runnable r) { - * tasks.offer(new Runnable() { - * public void run() { - * try { - * r.run(); - * } finally { - * scheduleNext(); - * } - * } - * }); - * if (active == null) { - * scheduleNext(); - * } - * } - * - * protected synchronized void scheduleNext() { - * if ((active = tasks.poll()) != null) { - * executor.execute(active); - * } - * } - * }</pre> - * - * The <tt>Executor</tt> implementations provided in this package - * implement {@link ExecutorService}, which is a more extensive - * interface. The {@link ThreadPoolExecutor} class provides an - * extensible thread pool implementation. The {@link Executors} class - * provides convenient factory methods for these Executors. - * - * <p>Memory consistency effects: Actions in a thread prior to - * submitting a {@code Runnable} object to an {@code Executor} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * its execution begins, perhaps in another thread. - * - * @since 1.5 - * @author Doug Lea - */ -public interface Executor { - - /** - * Executes the given command at some time in the future. The command - * may execute in a new thread, in a pooled thread, or in the calling - * thread, at the discretion of the <tt>Executor</tt> implementation. - * - * @param command the runnable task - * @throws RejectedExecutionException if this task cannot be - * accepted for execution. - * @throws NullPointerException if command is null - */ - void execute(Runnable command); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorCompletionService.java b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorCompletionService.java deleted file mode 100644 index 9b7a0e0..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorCompletionService.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A {@link CompletionService} that uses a supplied {@link Executor} - * to execute tasks. This class arranges that submitted tasks are, - * upon completion, placed on a queue accessible using <tt>take</tt>. - * The class is lightweight enough to be suitable for transient use - * when processing groups of tasks. - * - * <p> - * - * <b>Usage Examples.</b> - * - * Suppose you have a set of solvers for a certain problem, each - * returning a value of some type <tt>Result</tt>, and would like to - * run them concurrently, processing the results of each of them that - * return a non-null value, in some method <tt>use(Result r)</tt>. You - * could write this as: - * - * <pre> - * void solve(Executor e, - * Collection<Callable<Result>> solvers) - * throws InterruptedException, ExecutionException { - * CompletionService<Result> ecs - * = new ExecutorCompletionService<Result>(e); - * for (Callable<Result> s : solvers) - * ecs.submit(s); - * int n = solvers.size(); - * for (int i = 0; i < n; ++i) { - * Result r = ecs.take().get(); - * if (r != null) - * use(r); - * } - * } - * </pre> - * - * Suppose instead that you would like to use the first non-null result - * of the set of tasks, ignoring any that encounter exceptions, - * and cancelling all other tasks when the first one is ready: - * - * <pre> - * void solve(Executor e, - * Collection<Callable<Result>> solvers) - * throws InterruptedException { - * CompletionService<Result> ecs - * = new ExecutorCompletionService<Result>(e); - * int n = solvers.size(); - * List<Future<Result>> futures - * = new ArrayList<Future<Result>>(n); - * Result result = null; - * try { - * for (Callable<Result> s : solvers) - * futures.add(ecs.submit(s)); - * for (int i = 0; i < n; ++i) { - * try { - * Result r = ecs.take().get(); - * if (r != null) { - * result = r; - * break; - * } - * } catch (ExecutionException ignore) {} - * } - * } - * finally { - * for (Future<Result> f : futures) - * f.cancel(true); - * } - * - * if (result != null) - * use(result); - * } - * </pre> - */ -public class ExecutorCompletionService<V> implements CompletionService<V> { - private final Executor executor; - private final AbstractExecutorService aes; - private final BlockingQueue<Future<V>> completionQueue; - - /** - * FutureTask extension to enqueue upon completion - */ - private class QueueingFuture extends FutureTask<Void> { - QueueingFuture(RunnableFuture<V> task) { - super(task, null); - this.task = task; - } - protected void done() { completionQueue.add(task); } - private final Future<V> task; - } - - private RunnableFuture<V> newTaskFor(Callable<V> task) { - if (aes == null) - return new FutureTask<V>(task); - else - return aes.newTaskFor(task); - } - - private RunnableFuture<V> newTaskFor(Runnable task, V result) { - if (aes == null) - return new FutureTask<V>(task, result); - else - return aes.newTaskFor(task, result); - } - - /** - * Creates an ExecutorCompletionService using the supplied - * executor for base task execution and a - * {@link LinkedBlockingQueue} as a completion queue. - * - * @param executor the executor to use - * @throws NullPointerException if executor is <tt>null</tt> - */ - public ExecutorCompletionService(Executor executor) { - if (executor == null) - throw new NullPointerException(); - this.executor = executor; - this.aes = (executor instanceof AbstractExecutorService) ? - (AbstractExecutorService) executor : null; - this.completionQueue = new LinkedBlockingQueue<Future<V>>(); - } - - /** - * Creates an ExecutorCompletionService using the supplied - * executor for base task execution and the supplied queue as its - * completion queue. - * - * @param executor the executor to use - * @param completionQueue the queue to use as the completion queue - * normally one dedicated for use by this service - * @throws NullPointerException if executor or completionQueue are <tt>null</tt> - */ - public ExecutorCompletionService(Executor executor, - BlockingQueue<Future<V>> completionQueue) { - if (executor == null || completionQueue == null) - throw new NullPointerException(); - this.executor = executor; - this.aes = (executor instanceof AbstractExecutorService) ? - (AbstractExecutorService) executor : null; - this.completionQueue = completionQueue; - } - - public Future<V> submit(Callable<V> task) { - if (task == null) throw new NullPointerException(); - RunnableFuture<V> f = newTaskFor(task); - executor.execute(new QueueingFuture(f)); - return f; - } - - public Future<V> submit(Runnable task, V result) { - if (task == null) throw new NullPointerException(); - RunnableFuture<V> f = newTaskFor(task, result); - executor.execute(new QueueingFuture(f)); - return f; - } - - public Future<V> take() throws InterruptedException { - return completionQueue.take(); - } - - public Future<V> poll() { - return completionQueue.poll(); - } - - public Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException { - return completionQueue.poll(timeout, unit); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorService.java b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorService.java deleted file mode 100644 index 7773192..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorService.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.List; -import java.util.Collection; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; - -/** - * An {@link Executor} that provides methods to manage termination and - * methods that can produce a {@link Future} for tracking progress of - * one or more asynchronous tasks. - * - * <p> - * An <tt>ExecutorService</tt> can be shut down, which will cause it - * to stop accepting new tasks. After being shut down, the executor - * will eventually terminate, at which point no tasks are actively - * executing, no tasks are awaiting execution, and no new tasks can be - * submitted. An unused <tt>ExecutorService</tt> should be shut down - * to allow reclamation of its resources. - * - * <p> Method <tt>submit</tt> extends base method {@link - * Executor#execute} by creating and returning a {@link Future} that - * can be used to cancel execution and/or wait for completion. - * Methods <tt>invokeAny</tt> and <tt>invokeAll</tt> perform the most - * commonly useful forms of bulk execution, executing a collection of - * tasks and then waiting for at least one, or all, to - * complete. (Class {@link ExecutorCompletionService} can be used to - * write customized variants of these methods.) - * - * <p>The {@link Executors} class provides factory methods for the - * executor services provided in this package. - * - * <h3>Usage Example</h3> - * - * Here is a sketch of a network service in which threads in a thread - * pool service incoming requests. It uses the preconfigured {@link - * Executors#newFixedThreadPool} factory method: - * - * <pre> - * class NetworkService { - * private final ServerSocket serverSocket; - * private final ExecutorService pool; - * - * public NetworkService(int port, int poolSize) - * throws IOException { - * serverSocket = new ServerSocket(port); - * pool = Executors.newFixedThreadPool(poolSize); - * } - * - * public void serve() { - * try { - * for (;;) { - * pool.execute(new Handler(serverSocket.accept())); - * } - * } catch (IOException ex) { - * pool.shutdown(); - * } - * } - * } - * - * class Handler implements Runnable { - * private final Socket socket; - * Handler(Socket socket) { this.socket = socket; } - * public void run() { - * // read and service request - * } - * } - * </pre> - * - * <p>Memory consistency effects: Actions in a thread prior to the - * submission of a {@code Runnable} or {@code Callable} task to an - * {@code ExecutorService} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * any actions taken by that task, which in turn <i>happen-before</i> the - * result is retrieved via {@code Future.get()}. - * - * @since 1.5 - * @author Doug Lea - */ -public interface ExecutorService extends Executor { - - /** - * Initiates an orderly shutdown in which previously submitted - * tasks are executed, but no new tasks will be accepted. - * Invocation has no additional effect if already shut down. - * - * @throws SecurityException if a security manager exists and - * shutting down this ExecutorService may manipulate - * threads that the caller is not permitted to modify - * because it does not hold {@link - * java.lang.RuntimePermission}<tt>("modifyThread")</tt>, - * or the security manager's <tt>checkAccess</tt> method - * denies access. - */ - void shutdown(); - - /** - * Attempts to stop all actively executing tasks, halts the - * processing of waiting tasks, and returns a list of the tasks that were - * awaiting execution. - * - * <p>There are no guarantees beyond best-effort attempts to stop - * processing actively executing tasks. For example, typical - * implementations will cancel via {@link Thread#interrupt}, so any - * task that fails to respond to interrupts may never terminate. - * - * @return list of tasks that never commenced execution - * @throws SecurityException if a security manager exists and - * shutting down this ExecutorService may manipulate - * threads that the caller is not permitted to modify - * because it does not hold {@link - * java.lang.RuntimePermission}<tt>("modifyThread")</tt>, - * or the security manager's <tt>checkAccess</tt> method - * denies access. - */ - List<Runnable> shutdownNow(); - - /** - * Returns <tt>true</tt> if this executor has been shut down. - * - * @return <tt>true</tt> if this executor has been shut down - */ - boolean isShutdown(); - - /** - * Returns <tt>true</tt> if all tasks have completed following shut down. - * Note that <tt>isTerminated</tt> is never <tt>true</tt> unless - * either <tt>shutdown</tt> or <tt>shutdownNow</tt> was called first. - * - * @return <tt>true</tt> if all tasks have completed following shut down - */ - boolean isTerminated(); - - /** - * Blocks until all tasks have completed execution after a shutdown - * request, or the timeout occurs, or the current thread is - * interrupted, whichever happens first. - * - * @param timeout the maximum time to wait - * @param unit the time unit of the timeout argument - * @return <tt>true</tt> if this executor terminated and - * <tt>false</tt> if the timeout elapsed before termination - * @throws InterruptedException if interrupted while waiting - */ - boolean awaitTermination(long timeout, TimeUnit unit) - throws InterruptedException; - - - /** - * Submits a value-returning task for execution and returns a - * Future representing the pending results of the task. The - * Future's <tt>get</tt> method will return the task's result upon - * successful completion. - * - * <p> - * If you would like to immediately block waiting - * for a task, you can use constructions of the form - * <tt>result = exec.submit(aCallable).get();</tt> - * - * <p> Note: The {@link Executors} class includes a set of methods - * that can convert some other common closure-like objects, - * for example, {@link java.security.PrivilegedAction} to - * {@link Callable} form so they can be submitted. - * - * @param task the task to submit - * @return a Future representing pending completion of the task - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if the task is null - */ - <T> Future<T> submit(Callable<T> task); - - /** - * Submits a Runnable task for execution and returns a Future - * representing that task. The Future's <tt>get</tt> method will - * return the given result upon successful completion. - * - * @param task the task to submit - * @param result the result to return - * @return a Future representing pending completion of the task - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if the task is null - */ - <T> Future<T> submit(Runnable task, T result); - - /** - * Submits a Runnable task for execution and returns a Future - * representing that task. The Future's <tt>get</tt> method will - * return <tt>null</tt> upon <em>successful</em> completion. - * - * @param task the task to submit - * @return a Future representing pending completion of the task - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if the task is null - */ - Future<?> submit(Runnable task); - - /** - * Executes the given tasks, returning a list of Futures holding - * their status and results when all complete. - * {@link Future#isDone} is <tt>true</tt> for each - * element of the returned list. - * Note that a <em>completed</em> task could have - * terminated either normally or by throwing an exception. - * The results of this method are undefined if the given - * collection is modified while this operation is in progress. - * - * @param tasks the collection of tasks - * @return A list of Futures representing the tasks, in the same - * sequential order as produced by the iterator for the - * given task list, each of which has completed. - * @throws InterruptedException if interrupted while waiting, in - * which case unfinished tasks are cancelled. - * @throws NullPointerException if tasks or any of its elements are <tt>null</tt> - * @throws RejectedExecutionException if any task cannot be - * scheduled for execution - */ - - <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) - throws InterruptedException; - - /** - * Executes the given tasks, returning a list of Futures holding - * their status and results - * when all complete or the timeout expires, whichever happens first. - * {@link Future#isDone} is <tt>true</tt> for each - * element of the returned list. - * Upon return, tasks that have not completed are cancelled. - * Note that a <em>completed</em> task could have - * terminated either normally or by throwing an exception. - * The results of this method are undefined if the given - * collection is modified while this operation is in progress. - * - * @param tasks the collection of tasks - * @param timeout the maximum time to wait - * @param unit the time unit of the timeout argument - * @return a list of Futures representing the tasks, in the same - * sequential order as produced by the iterator for the - * given task list. If the operation did not time out, - * each task will have completed. If it did time out, some - * of these tasks will not have completed. - * @throws InterruptedException if interrupted while waiting, in - * which case unfinished tasks are cancelled - * @throws NullPointerException if tasks, any of its elements, or - * unit are <tt>null</tt> - * @throws RejectedExecutionException if any task cannot be scheduled - * for execution - */ - <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, - long timeout, TimeUnit unit) - throws InterruptedException; - - /** - * Executes the given tasks, returning the result - * of one that has completed successfully (i.e., without throwing - * an exception), if any do. Upon normal or exceptional return, - * tasks that have not completed are cancelled. - * The results of this method are undefined if the given - * collection is modified while this operation is in progress. - * - * @param tasks the collection of tasks - * @return the result returned by one of the tasks - * @throws InterruptedException if interrupted while waiting - * @throws NullPointerException if tasks or any of its elements - * are <tt>null</tt> - * @throws IllegalArgumentException if tasks is empty - * @throws ExecutionException if no task successfully completes - * @throws RejectedExecutionException if tasks cannot be scheduled - * for execution - */ - <T> T invokeAny(Collection<? extends Callable<T>> tasks) - throws InterruptedException, ExecutionException; - - /** - * Executes the given tasks, returning the result - * of one that has completed successfully (i.e., without throwing - * an exception), if any do before the given timeout elapses. - * Upon normal or exceptional return, tasks that have not - * completed are cancelled. - * The results of this method are undefined if the given - * collection is modified while this operation is in progress. - * - * @param tasks the collection of tasks - * @param timeout the maximum time to wait - * @param unit the time unit of the timeout argument - * @return the result returned by one of the tasks. - * @throws InterruptedException if interrupted while waiting - * @throws NullPointerException if tasks, any of its elements, or - * unit are <tt>null</tt> - * @throws TimeoutException if the given timeout elapses before - * any task successfully completes - * @throws ExecutionException if no task successfully completes - * @throws RejectedExecutionException if tasks cannot be scheduled - * for execution - */ - <T> T invokeAny(Collection<? extends Callable<T>> tasks, - long timeout, TimeUnit unit) - throws InterruptedException, ExecutionException, TimeoutException; -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Executors.java b/libjava/classpath/external/jsr166/java/util/concurrent/Executors.java deleted file mode 100644 index 18e6b33..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/Executors.java +++ /dev/null @@ -1,666 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; -import java.security.AccessControlException; - -/** - * Factory and utility methods for {@link Executor}, {@link - * ExecutorService}, {@link ScheduledExecutorService}, {@link - * ThreadFactory}, and {@link Callable} classes defined in this - * package. This class supports the following kinds of methods: - * - * <ul> - * <li> Methods that create and return an {@link ExecutorService} - * set up with commonly useful configuration settings. - * <li> Methods that create and return a {@link ScheduledExecutorService} - * set up with commonly useful configuration settings. - * <li> Methods that create and return a "wrapped" ExecutorService, that - * disables reconfiguration by making implementation-specific methods - * inaccessible. - * <li> Methods that create and return a {@link ThreadFactory} - * that sets newly created threads to a known state. - * <li> Methods that create and return a {@link Callable} - * out of other closure-like forms, so they can be used - * in execution methods requiring <tt>Callable</tt>. - * </ul> - * - * @since 1.5 - * @author Doug Lea - */ -public class Executors { - - /** - * Creates a thread pool that reuses a fixed number of threads - * operating off a shared unbounded queue. At any point, at most - * <tt>nThreads</tt> threads will be active processing tasks. - * If additional tasks are submitted when all threads are active, - * they will wait in the queue until a thread is available. - * If any thread terminates due to a failure during execution - * prior to shutdown, a new one will take its place if needed to - * execute subsequent tasks. The threads in the pool will exist - * until it is explicitly {@link ExecutorService#shutdown shutdown}. - * - * @param nThreads the number of threads in the pool - * @return the newly created thread pool - * @throws IllegalArgumentException if <tt>nThreads <= 0</tt> - */ - public static ExecutorService newFixedThreadPool(int nThreads) { - return new ThreadPoolExecutor(nThreads, nThreads, - 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<Runnable>()); - } - - /** - * Creates a thread pool that reuses a fixed number of threads - * operating off a shared unbounded queue, using the provided - * ThreadFactory to create new threads when needed. At any point, - * at most <tt>nThreads</tt> threads will be active processing - * tasks. If additional tasks are submitted when all threads are - * active, they will wait in the queue until a thread is - * available. If any thread terminates due to a failure during - * execution prior to shutdown, a new one will take its place if - * needed to execute subsequent tasks. The threads in the pool will - * exist until it is explicitly {@link ExecutorService#shutdown - * shutdown}. - * - * @param nThreads the number of threads in the pool - * @param threadFactory the factory to use when creating new threads - * @return the newly created thread pool - * @throws NullPointerException if threadFactory is null - * @throws IllegalArgumentException if <tt>nThreads <= 0</tt> - */ - public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { - return new ThreadPoolExecutor(nThreads, nThreads, - 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<Runnable>(), - threadFactory); - } - - /** - * Creates an Executor that uses a single worker thread operating - * off an unbounded queue. (Note however that if this single - * thread terminates due to a failure during execution prior to - * shutdown, a new one will take its place if needed to execute - * subsequent tasks.) Tasks are guaranteed to execute - * sequentially, and no more than one task will be active at any - * given time. Unlike the otherwise equivalent - * <tt>newFixedThreadPool(1)</tt> the returned executor is - * guaranteed not to be reconfigurable to use additional threads. - * - * @return the newly created single-threaded Executor - */ - public static ExecutorService newSingleThreadExecutor() { - return new FinalizableDelegatedExecutorService - (new ThreadPoolExecutor(1, 1, - 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<Runnable>())); - } - - /** - * Creates an Executor that uses a single worker thread operating - * off an unbounded queue, and uses the provided ThreadFactory to - * create a new thread when needed. Unlike the otherwise - * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the - * returned executor is guaranteed not to be reconfigurable to use - * additional threads. - * - * @param threadFactory the factory to use when creating new - * threads - * - * @return the newly created single-threaded Executor - * @throws NullPointerException if threadFactory is null - */ - public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { - return new FinalizableDelegatedExecutorService - (new ThreadPoolExecutor(1, 1, - 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<Runnable>(), - threadFactory)); - } - - /** - * Creates a thread pool that creates new threads as needed, but - * will reuse previously constructed threads when they are - * available. These pools will typically improve the performance - * of programs that execute many short-lived asynchronous tasks. - * Calls to <tt>execute</tt> will reuse previously constructed - * threads if available. If no existing thread is available, a new - * thread will be created and added to the pool. Threads that have - * not been used for sixty seconds are terminated and removed from - * the cache. Thus, a pool that remains idle for long enough will - * not consume any resources. Note that pools with similar - * properties but different details (for example, timeout parameters) - * may be created using {@link ThreadPoolExecutor} constructors. - * - * @return the newly created thread pool - */ - public static ExecutorService newCachedThreadPool() { - return new ThreadPoolExecutor(0, Integer.MAX_VALUE, - 60L, TimeUnit.SECONDS, - new SynchronousQueue<Runnable>()); - } - - /** - * Creates a thread pool that creates new threads as needed, but - * will reuse previously constructed threads when they are - * available, and uses the provided - * ThreadFactory to create new threads when needed. - * @param threadFactory the factory to use when creating new threads - * @return the newly created thread pool - * @throws NullPointerException if threadFactory is null - */ - public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { - return new ThreadPoolExecutor(0, Integer.MAX_VALUE, - 60L, TimeUnit.SECONDS, - new SynchronousQueue<Runnable>(), - threadFactory); - } - - /** - * Creates a single-threaded executor that can schedule commands - * to run after a given delay, or to execute periodically. - * (Note however that if this single - * thread terminates due to a failure during execution prior to - * shutdown, a new one will take its place if needed to execute - * subsequent tasks.) Tasks are guaranteed to execute - * sequentially, and no more than one task will be active at any - * given time. Unlike the otherwise equivalent - * <tt>newScheduledThreadPool(1)</tt> the returned executor is - * guaranteed not to be reconfigurable to use additional threads. - * @return the newly created scheduled executor - */ - public static ScheduledExecutorService newSingleThreadScheduledExecutor() { - return new DelegatedScheduledExecutorService - (new ScheduledThreadPoolExecutor(1)); - } - - /** - * Creates a single-threaded executor that can schedule commands - * to run after a given delay, or to execute periodically. (Note - * however that if this single thread terminates due to a failure - * during execution prior to shutdown, a new one will take its - * place if needed to execute subsequent tasks.) Tasks are - * guaranteed to execute sequentially, and no more than one task - * will be active at any given time. Unlike the otherwise - * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt> - * the returned executor is guaranteed not to be reconfigurable to - * use additional threads. - * @param threadFactory the factory to use when creating new - * threads - * @return a newly created scheduled executor - * @throws NullPointerException if threadFactory is null - */ - public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) { - return new DelegatedScheduledExecutorService - (new ScheduledThreadPoolExecutor(1, threadFactory)); - } - - /** - * Creates a thread pool that can schedule commands to run after a - * given delay, or to execute periodically. - * @param corePoolSize the number of threads to keep in the pool, - * even if they are idle. - * @return a newly created scheduled thread pool - * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> - */ - public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { - return new ScheduledThreadPoolExecutor(corePoolSize); - } - - /** - * Creates a thread pool that can schedule commands to run after a - * given delay, or to execute periodically. - * @param corePoolSize the number of threads to keep in the pool, - * even if they are idle. - * @param threadFactory the factory to use when the executor - * creates a new thread. - * @return a newly created scheduled thread pool - * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> - * @throws NullPointerException if threadFactory is null - */ - public static ScheduledExecutorService newScheduledThreadPool( - int corePoolSize, ThreadFactory threadFactory) { - return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); - } - - - /** - * Returns an object that delegates all defined {@link - * ExecutorService} methods to the given executor, but not any - * other methods that might otherwise be accessible using - * casts. This provides a way to safely "freeze" configuration and - * disallow tuning of a given concrete implementation. - * @param executor the underlying implementation - * @return an <tt>ExecutorService</tt> instance - * @throws NullPointerException if executor null - */ - public static ExecutorService unconfigurableExecutorService(ExecutorService executor) { - if (executor == null) - throw new NullPointerException(); - return new DelegatedExecutorService(executor); - } - - /** - * Returns an object that delegates all defined {@link - * ScheduledExecutorService} methods to the given executor, but - * not any other methods that might otherwise be accessible using - * casts. This provides a way to safely "freeze" configuration and - * disallow tuning of a given concrete implementation. - * @param executor the underlying implementation - * @return a <tt>ScheduledExecutorService</tt> instance - * @throws NullPointerException if executor null - */ - public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) { - if (executor == null) - throw new NullPointerException(); - return new DelegatedScheduledExecutorService(executor); - } - - /** - * Returns a default thread factory used to create new threads. - * This factory creates all new threads used by an Executor in the - * same {@link ThreadGroup}. If there is a {@link - * java.lang.SecurityManager}, it uses the group of {@link - * System#getSecurityManager}, else the group of the thread - * invoking this <tt>defaultThreadFactory</tt> method. Each new - * thread is created as a non-daemon thread with priority set to - * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum - * priority permitted in the thread group. New threads have names - * accessible via {@link Thread#getName} of - * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence - * number of this factory, and <em>M</em> is the sequence number - * of the thread created by this factory. - * @return a thread factory - */ - public static ThreadFactory defaultThreadFactory() { - return new DefaultThreadFactory(); - } - - /** - * Returns a thread factory used to create new threads that - * have the same permissions as the current thread. - * This factory creates threads with the same settings as {@link - * Executors#defaultThreadFactory}, additionally setting the - * AccessControlContext and contextClassLoader of new threads to - * be the same as the thread invoking this - * <tt>privilegedThreadFactory</tt> method. A new - * <tt>privilegedThreadFactory</tt> can be created within an - * {@link AccessController#doPrivileged} action setting the - * current thread's access control context to create threads with - * the selected permission settings holding within that action. - * - * <p> Note that while tasks running within such threads will have - * the same access control and class loader settings as the - * current thread, they need not have the same {@link - * java.lang.ThreadLocal} or {@link - * java.lang.InheritableThreadLocal} values. If necessary, - * particular values of thread locals can be set or reset before - * any task runs in {@link ThreadPoolExecutor} subclasses using - * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is - * necessary to initialize worker threads to have the same - * InheritableThreadLocal settings as some other designated - * thread, you can create a custom ThreadFactory in which that - * thread waits for and services requests to create others that - * will inherit its values. - * - * @return a thread factory - * @throws AccessControlException if the current access control - * context does not have permission to both get and set context - * class loader. - */ - public static ThreadFactory privilegedThreadFactory() { - return new PrivilegedThreadFactory(); - } - - /** - * Returns a {@link Callable} object that, when - * called, runs the given task and returns the given result. This - * can be useful when applying methods requiring a - * <tt>Callable</tt> to an otherwise resultless action. - * @param task the task to run - * @param result the result to return - * @return a callable object - * @throws NullPointerException if task null - */ - public static <T> Callable<T> callable(Runnable task, T result) { - if (task == null) - throw new NullPointerException(); - return new RunnableAdapter<T>(task, result); - } - - /** - * Returns a {@link Callable} object that, when - * called, runs the given task and returns <tt>null</tt>. - * @param task the task to run - * @return a callable object - * @throws NullPointerException if task null - */ - public static Callable<Object> callable(Runnable task) { - if (task == null) - throw new NullPointerException(); - return new RunnableAdapter<Object>(task, null); - } - - /** - * Returns a {@link Callable} object that, when - * called, runs the given privileged action and returns its result. - * @param action the privileged action to run - * @return a callable object - * @throws NullPointerException if action null - */ - public static Callable<Object> callable(final PrivilegedAction<?> action) { - if (action == null) - throw new NullPointerException(); - return new Callable<Object>() { - public Object call() { return action.run(); }}; - } - - /** - * Returns a {@link Callable} object that, when - * called, runs the given privileged exception action and returns - * its result. - * @param action the privileged exception action to run - * @return a callable object - * @throws NullPointerException if action null - */ - public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) { - if (action == null) - throw new NullPointerException(); - return new Callable<Object>() { - public Object call() throws Exception { return action.run(); }}; - } - - /** - * Returns a {@link Callable} object that will, when - * called, execute the given <tt>callable</tt> under the current - * access control context. This method should normally be - * invoked within an {@link AccessController#doPrivileged} action - * to create callables that will, if possible, execute under the - * selected permission settings holding within that action; or if - * not possible, throw an associated {@link - * AccessControlException}. - * @param callable the underlying task - * @return a callable object - * @throws NullPointerException if callable null - * - */ - public static <T> Callable<T> privilegedCallable(Callable<T> callable) { - if (callable == null) - throw new NullPointerException(); - return new PrivilegedCallable<T>(callable); - } - - /** - * Returns a {@link Callable} object that will, when - * called, execute the given <tt>callable</tt> under the current - * access control context, with the current context class loader - * as the context class loader. This method should normally be - * invoked within an {@link AccessController#doPrivileged} action - * to create callables that will, if possible, execute under the - * selected permission settings holding within that action; or if - * not possible, throw an associated {@link - * AccessControlException}. - * @param callable the underlying task - * - * @return a callable object - * @throws NullPointerException if callable null - * @throws AccessControlException if the current access control - * context does not have permission to both set and get context - * class loader. - */ - public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) { - if (callable == null) - throw new NullPointerException(); - return new PrivilegedCallableUsingCurrentClassLoader<T>(callable); - } - - // Non-public classes supporting the public methods - - /** - * A callable that runs given task and returns given result - */ - static final class RunnableAdapter<T> implements Callable<T> { - final Runnable task; - final T result; - RunnableAdapter(Runnable task, T result) { - this.task = task; - this.result = result; - } - public T call() { - task.run(); - return result; - } - } - - /** - * A callable that runs under established access control settings - */ - static final class PrivilegedCallable<T> implements Callable<T> { - private final AccessControlContext acc; - private final Callable<T> task; - private T result; - private Exception exception; - PrivilegedCallable(Callable<T> task) { - this.task = task; - this.acc = AccessController.getContext(); - } - - public T call() throws Exception { - AccessController.doPrivileged(new PrivilegedAction<T>() { - public T run() { - try { - result = task.call(); - } catch (Exception ex) { - exception = ex; - } - return null; - } - }, acc); - if (exception != null) - throw exception; - else - return result; - } - } - - /** - * A callable that runs under established access control settings and - * current ClassLoader - */ - static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> { - private final ClassLoader ccl; - private final AccessControlContext acc; - private final Callable<T> task; - private T result; - private Exception exception; - PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) { - this.task = task; - this.ccl = Thread.currentThread().getContextClassLoader(); - this.acc = AccessController.getContext(); - acc.checkPermission(new RuntimePermission("getContextClassLoader")); - acc.checkPermission(new RuntimePermission("setContextClassLoader")); - } - - public T call() throws Exception { - AccessController.doPrivileged(new PrivilegedAction<T>() { - public T run() { - ClassLoader savedcl = null; - Thread t = Thread.currentThread(); - try { - ClassLoader cl = t.getContextClassLoader(); - if (ccl != cl) { - t.setContextClassLoader(ccl); - savedcl = cl; - } - result = task.call(); - } catch (Exception ex) { - exception = ex; - } finally { - if (savedcl != null) - t.setContextClassLoader(savedcl); - } - return null; - } - }, acc); - if (exception != null) - throw exception; - else - return result; - } - } - - /** - * The default thread factory - */ - static class DefaultThreadFactory implements ThreadFactory { - static final AtomicInteger poolNumber = new AtomicInteger(1); - final ThreadGroup group; - final AtomicInteger threadNumber = new AtomicInteger(1); - final String namePrefix; - - DefaultThreadFactory() { - SecurityManager s = System.getSecurityManager(); - group = (s != null)? s.getThreadGroup() : - Thread.currentThread().getThreadGroup(); - namePrefix = "pool-" + - poolNumber.getAndIncrement() + - "-thread-"; - } - - public Thread newThread(Runnable r) { - Thread t = new Thread(group, r, - namePrefix + threadNumber.getAndIncrement(), - 0); - if (t.isDaemon()) - t.setDaemon(false); - if (t.getPriority() != Thread.NORM_PRIORITY) - t.setPriority(Thread.NORM_PRIORITY); - return t; - } - } - - /** - * Thread factory capturing access control and class loader - */ - static class PrivilegedThreadFactory extends DefaultThreadFactory { - private final ClassLoader ccl; - private final AccessControlContext acc; - - PrivilegedThreadFactory() { - super(); - this.ccl = Thread.currentThread().getContextClassLoader(); - this.acc = AccessController.getContext(); - acc.checkPermission(new RuntimePermission("setContextClassLoader")); - } - - public Thread newThread(final Runnable r) { - return super.newThread(new Runnable() { - public void run() { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - Thread.currentThread().setContextClassLoader(ccl); - r.run(); - return null; - } - }, acc); - } - }); - } - - } - - /** - * A wrapper class that exposes only the ExecutorService methods - * of an ExecutorService implementation. - */ - static class DelegatedExecutorService extends AbstractExecutorService { - private final ExecutorService e; - DelegatedExecutorService(ExecutorService executor) { e = executor; } - public void execute(Runnable command) { e.execute(command); } - public void shutdown() { e.shutdown(); } - public List<Runnable> shutdownNow() { return e.shutdownNow(); } - public boolean isShutdown() { return e.isShutdown(); } - public boolean isTerminated() { return e.isTerminated(); } - public boolean awaitTermination(long timeout, TimeUnit unit) - throws InterruptedException { - return e.awaitTermination(timeout, unit); - } - public Future<?> submit(Runnable task) { - return e.submit(task); - } - public <T> Future<T> submit(Callable<T> task) { - return e.submit(task); - } - public <T> Future<T> submit(Runnable task, T result) { - return e.submit(task, result); - } - public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) - throws InterruptedException { - return e.invokeAll(tasks); - } - public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, - long timeout, TimeUnit unit) - throws InterruptedException { - return e.invokeAll(tasks, timeout, unit); - } - public <T> T invokeAny(Collection<? extends Callable<T>> tasks) - throws InterruptedException, ExecutionException { - return e.invokeAny(tasks); - } - public <T> T invokeAny(Collection<? extends Callable<T>> tasks, - long timeout, TimeUnit unit) - throws InterruptedException, ExecutionException, TimeoutException { - return e.invokeAny(tasks, timeout, unit); - } - } - - static class FinalizableDelegatedExecutorService - extends DelegatedExecutorService { - FinalizableDelegatedExecutorService(ExecutorService executor) { - super(executor); - } - protected void finalize() { - super.shutdown(); - } - } - - /** - * A wrapper class that exposes only the ScheduledExecutorService - * methods of a ScheduledExecutorService implementation. - */ - static class DelegatedScheduledExecutorService - extends DelegatedExecutorService - implements ScheduledExecutorService { - private final ScheduledExecutorService e; - DelegatedScheduledExecutorService(ScheduledExecutorService executor) { - super(executor); - e = executor; - } - public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { - return e.schedule(command, delay, unit); - } - public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) { - return e.schedule(callable, delay, unit); - } - public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { - return e.scheduleAtFixedRate(command, initialDelay, period, unit); - } - public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { - return e.scheduleWithFixedDelay(command, initialDelay, delay, unit); - } - } - - - /** Cannot instantiate. */ - private Executors() {} -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Future.java b/libjava/classpath/external/jsr166/java/util/concurrent/Future.java deleted file mode 100644 index 0459ee4..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/Future.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A <tt>Future</tt> represents the result of an asynchronous - * computation. Methods are provided to check if the computation is - * complete, to wait for its completion, and to retrieve the result of - * the computation. The result can only be retrieved using method - * <tt>get</tt> when the computation has completed, blocking if - * necessary until it is ready. Cancellation is performed by the - * <tt>cancel</tt> method. Additional methods are provided to - * determine if the task completed normally or was cancelled. Once a - * computation has completed, the computation cannot be cancelled. - * If you would like to use a <tt>Future</tt> for the sake - * of cancellability but not provide a usable result, you can - * declare types of the form <tt>Future<?></tt> and - * return <tt>null</tt> as a result of the underlying task. - * - * <p> - * <b>Sample Usage</b> (Note that the following classes are all - * made-up.) <p> - * <pre> - * interface ArchiveSearcher { String search(String target); } - * class App { - * ExecutorService executor = ... - * ArchiveSearcher searcher = ... - * void showSearch(final String target) - * throws InterruptedException { - * Future<String> future - * = executor.submit(new Callable<String>() { - * public String call() { - * return searcher.search(target); - * }}); - * displayOtherThings(); // do other things while searching - * try { - * displayText(future.get()); // use future - * } catch (ExecutionException ex) { cleanup(); return; } - * } - * } - * </pre> - * - * The {@link FutureTask} class is an implementation of <tt>Future</tt> that - * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>. - * For example, the above construction with <tt>submit</tt> could be replaced by: - * <pre> - * FutureTask<String> future = - * new FutureTask<String>(new Callable<String>() { - * public String call() { - * return searcher.search(target); - * }}); - * executor.execute(future); - * </pre> - * - * <p>Memory consistency effects: Actions taken by the asynchronous computation - * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a> - * actions following the corresponding {@code Future.get()} in another thread. - * - * @see FutureTask - * @see Executor - * @since 1.5 - * @author Doug Lea - * @param <V> The result type returned by this Future's <tt>get</tt> method - */ -public interface Future<V> { - - /** - * Attempts to cancel execution of this task. This attempt will - * fail if the task has already completed, has already been cancelled, - * or could not be cancelled for some other reason. If successful, - * and this task has not started when <tt>cancel</tt> is called, - * this task should never run. If the task has already started, - * then the <tt>mayInterruptIfRunning</tt> parameter determines - * whether the thread executing this task should be interrupted in - * an attempt to stop the task. - * - * <p>After this method returns, subsequent calls to {@link #isDone} will - * always return <tt>true</tt>. Subsequent calls to {@link #isCancelled} - * will always return <tt>true</tt> if this method returned <tt>true</tt>. - * - * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this - * task should be interrupted; otherwise, in-progress tasks are allowed - * to complete - * @return <tt>false</tt> if the task could not be cancelled, - * typically because it has already completed normally; - * <tt>true</tt> otherwise - */ - boolean cancel(boolean mayInterruptIfRunning); - - /** - * Returns <tt>true</tt> if this task was cancelled before it completed - * normally. - * - * @return <tt>true</tt> if this task was cancelled before it completed - */ - boolean isCancelled(); - - /** - * Returns <tt>true</tt> if this task completed. - * - * Completion may be due to normal termination, an exception, or - * cancellation -- in all of these cases, this method will return - * <tt>true</tt>. - * - * @return <tt>true</tt> if this task completed - */ - boolean isDone(); - - /** - * Waits if necessary for the computation to complete, and then - * retrieves its result. - * - * @return the computed result - * @throws CancellationException if the computation was cancelled - * @throws ExecutionException if the computation threw an - * exception - * @throws InterruptedException if the current thread was interrupted - * while waiting - */ - V get() throws InterruptedException, ExecutionException; - - /** - * Waits if necessary for at most the given time for the computation - * to complete, and then retrieves its result, if available. - * - * @param timeout the maximum time to wait - * @param unit the time unit of the timeout argument - * @return the computed result - * @throws CancellationException if the computation was cancelled - * @throws ExecutionException if the computation threw an - * exception - * @throws InterruptedException if the current thread was interrupted - * while waiting - * @throws TimeoutException if the wait timed out - */ - V get(long timeout, TimeUnit unit) - throws InterruptedException, ExecutionException, TimeoutException; -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/FutureTask.java b/libjava/classpath/external/jsr166/java/util/concurrent/FutureTask.java deleted file mode 100644 index 9474240..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/FutureTask.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.locks.*; - -/** - * A cancellable asynchronous computation. This class provides a base - * implementation of {@link Future}, with methods to start and cancel - * a computation, query to see if the computation is complete, and - * retrieve the result of the computation. The result can only be - * retrieved when the computation has completed; the <tt>get</tt> - * method will block if the computation has not yet completed. Once - * the computation has completed, the computation cannot be restarted - * or cancelled. - * - * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or - * {@link java.lang.Runnable} object. Because <tt>FutureTask</tt> - * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be - * submitted to an {@link Executor} for execution. - * - * <p>In addition to serving as a standalone class, this class provides - * <tt>protected</tt> functionality that may be useful when creating - * customized task classes. - * - * @since 1.5 - * @author Doug Lea - * @param <V> The result type returned by this FutureTask's <tt>get</tt> method - */ -public class FutureTask<V> implements RunnableFuture<V> { - /** Synchronization control for FutureTask */ - private final Sync sync; - - /** - * Creates a <tt>FutureTask</tt> that will upon running, execute the - * given <tt>Callable</tt>. - * - * @param callable the callable task - * @throws NullPointerException if callable is null - */ - public FutureTask(Callable<V> callable) { - if (callable == null) - throw new NullPointerException(); - sync = new Sync(callable); - } - - /** - * Creates a <tt>FutureTask</tt> that will upon running, execute the - * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the - * given result on successful completion. - * - * @param runnable the runnable task - * @param result the result to return on successful completion. If - * you don't need a particular result, consider using - * constructions of the form: - * <tt>Future<?> f = new FutureTask<Object>(runnable, null)</tt> - * @throws NullPointerException if runnable is null - */ - public FutureTask(Runnable runnable, V result) { - sync = new Sync(Executors.callable(runnable, result)); - } - - public boolean isCancelled() { - return sync.innerIsCancelled(); - } - - public boolean isDone() { - return sync.innerIsDone(); - } - - public boolean cancel(boolean mayInterruptIfRunning) { - return sync.innerCancel(mayInterruptIfRunning); - } - - /** - * @throws CancellationException {@inheritDoc} - */ - public V get() throws InterruptedException, ExecutionException { - return sync.innerGet(); - } - - /** - * @throws CancellationException {@inheritDoc} - */ - public V get(long timeout, TimeUnit unit) - throws InterruptedException, ExecutionException, TimeoutException { - return sync.innerGet(unit.toNanos(timeout)); - } - - /** - * Protected method invoked when this task transitions to state - * <tt>isDone</tt> (whether normally or via cancellation). The - * default implementation does nothing. Subclasses may override - * this method to invoke completion callbacks or perform - * bookkeeping. Note that you can query status inside the - * implementation of this method to determine whether this task - * has been cancelled. - */ - protected void done() { } - - /** - * Sets the result of this Future to the given value unless - * this future has already been set or has been cancelled. - * This method is invoked internally by the <tt>run</tt> method - * upon successful completion of the computation. - * @param v the value - */ - protected void set(V v) { - sync.innerSet(v); - } - - /** - * Causes this future to report an <tt>ExecutionException</tt> - * with the given throwable as its cause, unless this Future has - * already been set or has been cancelled. - * This method is invoked internally by the <tt>run</tt> method - * upon failure of the computation. - * @param t the cause of failure - */ - protected void setException(Throwable t) { - sync.innerSetException(t); - } - - // The following (duplicated) doc comment can be removed once - // - // 6270645: Javadoc comments should be inherited from most derived - // superinterface or superclass - // is fixed. - /** - * Sets this Future to the result of its computation - * unless it has been cancelled. - */ - public void run() { - sync.innerRun(); - } - - /** - * Executes the computation without setting its result, and then - * resets this Future to initial state, failing to do so if the - * computation encounters an exception or is cancelled. This is - * designed for use with tasks that intrinsically execute more - * than once. - * @return true if successfully run and reset - */ - protected boolean runAndReset() { - return sync.innerRunAndReset(); - } - - /** - * Synchronization control for FutureTask. Note that this must be - * a non-static inner class in order to invoke the protected - * <tt>done</tt> method. For clarity, all inner class support - * methods are same as outer, prefixed with "inner". - * - * Uses AQS sync state to represent run status - */ - private final class Sync extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = -7828117401763700385L; - - /** State value representing that task is running */ - private static final int RUNNING = 1; - /** State value representing that task ran */ - private static final int RAN = 2; - /** State value representing that task was cancelled */ - private static final int CANCELLED = 4; - - /** The underlying callable */ - private final Callable<V> callable; - /** The result to return from get() */ - private V result; - /** The exception to throw from get() */ - private Throwable exception; - - /** - * The thread running task. When nulled after set/cancel, this - * indicates that the results are accessible. Must be - * volatile, to ensure visibility upon completion. - */ - private volatile Thread runner; - - Sync(Callable<V> callable) { - this.callable = callable; - } - - private boolean ranOrCancelled(int state) { - return (state & (RAN | CANCELLED)) != 0; - } - - /** - * Implements AQS base acquire to succeed if ran or cancelled - */ - protected int tryAcquireShared(int ignore) { - return innerIsDone()? 1 : -1; - } - - /** - * Implements AQS base release to always signal after setting - * final done status by nulling runner thread. - */ - protected boolean tryReleaseShared(int ignore) { - runner = null; - return true; - } - - boolean innerIsCancelled() { - return getState() == CANCELLED; - } - - boolean innerIsDone() { - return ranOrCancelled(getState()) && runner == null; - } - - V innerGet() throws InterruptedException, ExecutionException { - acquireSharedInterruptibly(0); - if (getState() == CANCELLED) - throw new CancellationException(); - if (exception != null) - throw new ExecutionException(exception); - return result; - } - - V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException { - if (!tryAcquireSharedNanos(0, nanosTimeout)) - throw new TimeoutException(); - if (getState() == CANCELLED) - throw new CancellationException(); - if (exception != null) - throw new ExecutionException(exception); - return result; - } - - void innerSet(V v) { - for (;;) { - int s = getState(); - if (s == RAN) - return; - if (s == CANCELLED) { - // aggressively release to set runner to null, - // in case we are racing with a cancel request - // that will try to interrupt runner - releaseShared(0); - return; - } - if (compareAndSetState(s, RAN)) { - result = v; - releaseShared(0); - done(); - return; - } - } - } - - void innerSetException(Throwable t) { - for (;;) { - int s = getState(); - if (s == RAN) - return; - if (s == CANCELLED) { - // aggressively release to set runner to null, - // in case we are racing with a cancel request - // that will try to interrupt runner - releaseShared(0); - return; - } - if (compareAndSetState(s, RAN)) { - exception = t; - result = null; - releaseShared(0); - done(); - return; - } - } - } - - boolean innerCancel(boolean mayInterruptIfRunning) { - for (;;) { - int s = getState(); - if (ranOrCancelled(s)) - return false; - if (compareAndSetState(s, CANCELLED)) - break; - } - if (mayInterruptIfRunning) { - Thread r = runner; - if (r != null) - r.interrupt(); - } - releaseShared(0); - done(); - return true; - } - - void innerRun() { - if (!compareAndSetState(0, RUNNING)) - return; - try { - runner = Thread.currentThread(); - if (getState() == RUNNING) // recheck after setting thread - innerSet(callable.call()); - else - releaseShared(0); // cancel - } catch (Throwable ex) { - innerSetException(ex); - } - } - - boolean innerRunAndReset() { - if (!compareAndSetState(0, RUNNING)) - return false; - try { - runner = Thread.currentThread(); - if (getState() == RUNNING) - callable.call(); // don't set result - runner = null; - return compareAndSetState(RUNNING, 0); - } catch (Throwable ex) { - innerSetException(ex); - return false; - } - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingDeque.java b/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingDeque.java deleted file mode 100644 index 2dc8fa8..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingDeque.java +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; -import java.util.concurrent.locks.*; - -/** - * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on - * linked nodes. - * - * <p> The optional capacity bound constructor argument serves as a - * way to prevent excessive expansion. The capacity, if unspecified, - * is equal to {@link Integer#MAX_VALUE}. Linked nodes are - * dynamically created upon each insertion unless this would bring the - * deque above capacity. - * - * <p>Most operations run in constant time (ignoring time spent - * blocking). Exceptions include {@link #remove(Object) remove}, - * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link - * #removeLastOccurrence removeLastOccurrence}, {@link #contains - * contains}, {@link #iterator iterator.remove()}, and the bulk - * operations, all of which run in linear time. - * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.6 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ -public class LinkedBlockingDeque<E> - extends AbstractQueue<E> - implements BlockingDeque<E>, java.io.Serializable { - - /* - * Implemented as a simple doubly-linked list protected by a - * single lock and using conditions to manage blocking. - */ - - /* - * We have "diamond" multiple interface/abstract class inheritance - * here, and that introduces ambiguities. Often we want the - * BlockingDeque javadoc combined with the AbstractQueue - * implementation, so a lot of method specs are duplicated here. - */ - - private static final long serialVersionUID = -387911632671998426L; - - /** Doubly-linked list node class */ - static final class Node<E> { - E item; - Node<E> prev; - Node<E> next; - Node(E x, Node<E> p, Node<E> n) { - item = x; - prev = p; - next = n; - } - } - - /** Pointer to first node */ - private transient Node<E> first; - /** Pointer to last node */ - private transient Node<E> last; - /** Number of items in the deque */ - private transient int count; - /** Maximum number of items in the deque */ - private final int capacity; - /** Main lock guarding all access */ - private final ReentrantLock lock = new ReentrantLock(); - /** Condition for waiting takes */ - private final Condition notEmpty = lock.newCondition(); - /** Condition for waiting puts */ - private final Condition notFull = lock.newCondition(); - - /** - * Creates a <tt>LinkedBlockingDeque</tt> with a capacity of - * {@link Integer#MAX_VALUE}. - */ - public LinkedBlockingDeque() { - this(Integer.MAX_VALUE); - } - - /** - * Creates a <tt>LinkedBlockingDeque</tt> with the given (fixed) capacity. - * - * @param capacity the capacity of this deque - * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1 - */ - public LinkedBlockingDeque(int capacity) { - if (capacity <= 0) throw new IllegalArgumentException(); - this.capacity = capacity; - } - - /** - * Creates a <tt>LinkedBlockingDeque</tt> with a capacity of - * {@link Integer#MAX_VALUE}, initially containing the elements of - * the given collection, added in traversal order of the - * collection's iterator. - * - * @param c the collection of elements to initially contain - * @throws NullPointerException if the specified collection or any - * of its elements are null - */ - public LinkedBlockingDeque(Collection<? extends E> c) { - this(Integer.MAX_VALUE); - for (E e : c) - add(e); - } - - - // Basic linking and unlinking operations, called only while holding lock - - /** - * Links e as first element, or returns false if full. - */ - private boolean linkFirst(E e) { - if (count >= capacity) - return false; - ++count; - Node<E> f = first; - Node<E> x = new Node<E>(e, null, f); - first = x; - if (last == null) - last = x; - else - f.prev = x; - notEmpty.signal(); - return true; - } - - /** - * Links e as last element, or returns false if full. - */ - private boolean linkLast(E e) { - if (count >= capacity) - return false; - ++count; - Node<E> l = last; - Node<E> x = new Node<E>(e, l, null); - last = x; - if (first == null) - first = x; - else - l.next = x; - notEmpty.signal(); - return true; - } - - /** - * Removes and returns first element, or null if empty. - */ - private E unlinkFirst() { - Node<E> f = first; - if (f == null) - return null; - Node<E> n = f.next; - first = n; - if (n == null) - last = null; - else - n.prev = null; - --count; - notFull.signal(); - return f.item; - } - - /** - * Removes and returns last element, or null if empty. - */ - private E unlinkLast() { - Node<E> l = last; - if (l == null) - return null; - Node<E> p = l.prev; - last = p; - if (p == null) - first = null; - else - p.next = null; - --count; - notFull.signal(); - return l.item; - } - - /** - * Unlink e - */ - private void unlink(Node<E> x) { - Node<E> p = x.prev; - Node<E> n = x.next; - if (p == null) { - if (n == null) - first = last = null; - else { - n.prev = null; - first = n; - } - } else if (n == null) { - p.next = null; - last = p; - } else { - p.next = n; - n.prev = p; - } - --count; - notFull.signalAll(); - } - - // BlockingDeque methods - - /** - * @throws IllegalStateException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public void addFirst(E e) { - if (!offerFirst(e)) - throw new IllegalStateException("Deque full"); - } - - /** - * @throws IllegalStateException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public void addLast(E e) { - if (!offerLast(e)) - throw new IllegalStateException("Deque full"); - } - - /** - * @throws NullPointerException {@inheritDoc} - */ - public boolean offerFirst(E e) { - if (e == null) throw new NullPointerException(); - lock.lock(); - try { - return linkFirst(e); - } finally { - lock.unlock(); - } - } - - /** - * @throws NullPointerException {@inheritDoc} - */ - public boolean offerLast(E e) { - if (e == null) throw new NullPointerException(); - lock.lock(); - try { - return linkLast(e); - } finally { - lock.unlock(); - } - } - - /** - * @throws NullPointerException {@inheritDoc} - * @throws InterruptedException {@inheritDoc} - */ - public void putFirst(E e) throws InterruptedException { - if (e == null) throw new NullPointerException(); - lock.lock(); - try { - while (!linkFirst(e)) - notFull.await(); - } finally { - lock.unlock(); - } - } - - /** - * @throws NullPointerException {@inheritDoc} - * @throws InterruptedException {@inheritDoc} - */ - public void putLast(E e) throws InterruptedException { - if (e == null) throw new NullPointerException(); - lock.lock(); - try { - while (!linkLast(e)) - notFull.await(); - } finally { - lock.unlock(); - } - } - - /** - * @throws NullPointerException {@inheritDoc} - * @throws InterruptedException {@inheritDoc} - */ - public boolean offerFirst(E e, long timeout, TimeUnit unit) - throws InterruptedException { - if (e == null) throw new NullPointerException(); - long nanos = unit.toNanos(timeout); - lock.lockInterruptibly(); - try { - for (;;) { - if (linkFirst(e)) - return true; - if (nanos <= 0) - return false; - nanos = notFull.awaitNanos(nanos); - } - } finally { - lock.unlock(); - } - } - - /** - * @throws NullPointerException {@inheritDoc} - * @throws InterruptedException {@inheritDoc} - */ - public boolean offerLast(E e, long timeout, TimeUnit unit) - throws InterruptedException { - if (e == null) throw new NullPointerException(); - long nanos = unit.toNanos(timeout); - lock.lockInterruptibly(); - try { - for (;;) { - if (linkLast(e)) - return true; - if (nanos <= 0) - return false; - nanos = notFull.awaitNanos(nanos); - } - } finally { - lock.unlock(); - } - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E removeFirst() { - E x = pollFirst(); - if (x == null) throw new NoSuchElementException(); - return x; - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E removeLast() { - E x = pollLast(); - if (x == null) throw new NoSuchElementException(); - return x; - } - - public E pollFirst() { - lock.lock(); - try { - return unlinkFirst(); - } finally { - lock.unlock(); - } - } - - public E pollLast() { - lock.lock(); - try { - return unlinkLast(); - } finally { - lock.unlock(); - } - } - - public E takeFirst() throws InterruptedException { - lock.lock(); - try { - E x; - while ( (x = unlinkFirst()) == null) - notEmpty.await(); - return x; - } finally { - lock.unlock(); - } - } - - public E takeLast() throws InterruptedException { - lock.lock(); - try { - E x; - while ( (x = unlinkLast()) == null) - notEmpty.await(); - return x; - } finally { - lock.unlock(); - } - } - - public E pollFirst(long timeout, TimeUnit unit) - throws InterruptedException { - long nanos = unit.toNanos(timeout); - lock.lockInterruptibly(); - try { - for (;;) { - E x = unlinkFirst(); - if (x != null) - return x; - if (nanos <= 0) - return null; - nanos = notEmpty.awaitNanos(nanos); - } - } finally { - lock.unlock(); - } - } - - public E pollLast(long timeout, TimeUnit unit) - throws InterruptedException { - long nanos = unit.toNanos(timeout); - lock.lockInterruptibly(); - try { - for (;;) { - E x = unlinkLast(); - if (x != null) - return x; - if (nanos <= 0) - return null; - nanos = notEmpty.awaitNanos(nanos); - } - } finally { - lock.unlock(); - } - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E getFirst() { - E x = peekFirst(); - if (x == null) throw new NoSuchElementException(); - return x; - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E getLast() { - E x = peekLast(); - if (x == null) throw new NoSuchElementException(); - return x; - } - - public E peekFirst() { - lock.lock(); - try { - return (first == null) ? null : first.item; - } finally { - lock.unlock(); - } - } - - public E peekLast() { - lock.lock(); - try { - return (last == null) ? null : last.item; - } finally { - lock.unlock(); - } - } - - public boolean removeFirstOccurrence(Object o) { - if (o == null) return false; - lock.lock(); - try { - for (Node<E> p = first; p != null; p = p.next) { - if (o.equals(p.item)) { - unlink(p); - return true; - } - } - return false; - } finally { - lock.unlock(); - } - } - - public boolean removeLastOccurrence(Object o) { - if (o == null) return false; - lock.lock(); - try { - for (Node<E> p = last; p != null; p = p.prev) { - if (o.equals(p.item)) { - unlink(p); - return true; - } - } - return false; - } finally { - lock.unlock(); - } - } - - // BlockingQueue methods - - /** - * Inserts the specified element at the end of this deque unless it would - * violate capacity restrictions. When using a capacity-restricted deque, - * it is generally preferable to use method {@link #offer(Object) offer}. - * - * <p>This method is equivalent to {@link #addLast}. - * - * @throws IllegalStateException if the element cannot be added at this - * time due to capacity restrictions - * @throws NullPointerException if the specified element is null - */ - public boolean add(E e) { - addLast(e); - return true; - } - - /** - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e) { - return offerLast(e); - } - - /** - * @throws NullPointerException {@inheritDoc} - * @throws InterruptedException {@inheritDoc} - */ - public void put(E e) throws InterruptedException { - putLast(e); - } - - /** - * @throws NullPointerException {@inheritDoc} - * @throws InterruptedException {@inheritDoc} - */ - public boolean offer(E e, long timeout, TimeUnit unit) - throws InterruptedException { - return offerLast(e, timeout, unit); - } - - /** - * Retrieves and removes the head of the queue represented by this deque. - * This method differs from {@link #poll poll} only in that it throws an - * exception if this deque is empty. - * - * <p>This method is equivalent to {@link #removeFirst() removeFirst}. - * - * @return the head of the queue represented by this deque - * @throws NoSuchElementException if this deque is empty - */ - public E remove() { - return removeFirst(); - } - - public E poll() { - return pollFirst(); - } - - public E take() throws InterruptedException { - return takeFirst(); - } - - public E poll(long timeout, TimeUnit unit) throws InterruptedException { - return pollFirst(timeout, unit); - } - - /** - * Retrieves, but does not remove, the head of the queue represented by - * this deque. This method differs from {@link #peek peek} only in that - * it throws an exception if this deque is empty. - * - * <p>This method is equivalent to {@link #getFirst() getFirst}. - * - * @return the head of the queue represented by this deque - * @throws NoSuchElementException if this deque is empty - */ - public E element() { - return getFirst(); - } - - public E peek() { - return peekFirst(); - } - - /** - * Returns the number of additional elements that this deque can ideally - * (in the absence of memory or resource constraints) accept without - * blocking. This is always equal to the initial capacity of this deque - * less the current <tt>size</tt> of this deque. - * - * <p>Note that you <em>cannot</em> always tell if an attempt to insert - * an element will succeed by inspecting <tt>remainingCapacity</tt> - * because it may be the case that another thread is about to - * insert or remove an element. - */ - public int remainingCapacity() { - lock.lock(); - try { - return capacity - count; - } finally { - lock.unlock(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - lock.lock(); - try { - for (Node<E> p = first; p != null; p = p.next) - c.add(p.item); - int n = count; - count = 0; - first = last = null; - notFull.signalAll(); - return n; - } finally { - lock.unlock(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c, int maxElements) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - lock.lock(); - try { - int n = 0; - while (n < maxElements && first != null) { - c.add(first.item); - first.prev = null; - first = first.next; - --count; - ++n; - } - if (first == null) - last = null; - notFull.signalAll(); - return n; - } finally { - lock.unlock(); - } - } - - // Stack methods - - /** - * @throws IllegalStateException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public void push(E e) { - addFirst(e); - } - - /** - * @throws NoSuchElementException {@inheritDoc} - */ - public E pop() { - return removeFirst(); - } - - // Collection methods - - /** - * Removes the first occurrence of the specified element from this deque. - * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that - * <tt>o.equals(e)</tt> (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element - * (or equivalently, if this deque changed as a result of the call). - * - * <p>This method is equivalent to - * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}. - * - * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if this deque changed as a result of the call - */ - public boolean remove(Object o) { - return removeFirstOccurrence(o); - } - - /** - * Returns the number of elements in this deque. - * - * @return the number of elements in this deque - */ - public int size() { - lock.lock(); - try { - return count; - } finally { - lock.unlock(); - } - } - - /** - * Returns <tt>true</tt> if this deque contains the specified element. - * More formally, returns <tt>true</tt> if and only if this deque contains - * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. - * - * @param o object to be checked for containment in this deque - * @return <tt>true</tt> if this deque contains the specified element - */ - public boolean contains(Object o) { - if (o == null) return false; - lock.lock(); - try { - for (Node<E> p = first; p != null; p = p.next) - if (o.equals(p.item)) - return true; - return false; - } finally { - lock.unlock(); - } - } - - /** - * Variant of removeFirstOccurrence needed by iterator.remove. - * Searches for the node, not its contents. - */ - boolean removeNode(Node<E> e) { - lock.lock(); - try { - for (Node<E> p = first; p != null; p = p.next) { - if (p == e) { - unlink(p); - return true; - } - } - return false; - } finally { - lock.unlock(); - } - } - - /** - * Returns an array containing all of the elements in this deque, in - * proper sequence (from first to last element). - * - * <p>The returned array will be "safe" in that no references to it are - * maintained by this deque. (In other words, this method must allocate - * a new array). The caller is thus free to modify the returned array. - * - * <p>This method acts as bridge between array-based and collection-based - * APIs. - * - * @return an array containing all of the elements in this deque - */ - public Object[] toArray() { - lock.lock(); - try { - Object[] a = new Object[count]; - int k = 0; - for (Node<E> p = first; p != null; p = p.next) - a[k++] = p.item; - return a; - } finally { - lock.unlock(); - } - } - - /** - * Returns an array containing all of the elements in this deque, in - * proper sequence; the runtime type of the returned array is that of - * the specified array. If the deque fits in the specified array, it - * is returned therein. Otherwise, a new array is allocated with the - * runtime type of the specified array and the size of this deque. - * - * <p>If this deque fits in the specified array with room to spare - * (i.e., the array has more elements than this deque), the element in - * the array immediately following the end of the deque is set to - * <tt>null</tt>. - * - * <p>Like the {@link #toArray()} method, this method acts as bridge between - * array-based and collection-based APIs. Further, this method allows - * precise control over the runtime type of the output array, and may, - * under certain circumstances, be used to save allocation costs. - * - * <p>Suppose <tt>x</tt> is a deque known to contain only strings. - * The following code can be used to dump the deque into a newly - * allocated array of <tt>String</tt>: - * - * <pre> - * String[] y = x.toArray(new String[0]);</pre> - * - * Note that <tt>toArray(new Object[0])</tt> is identical in function to - * <tt>toArray()</tt>. - * - * @param a the array into which the elements of the deque are to - * be stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose - * @return an array containing all of the elements in this deque - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in - * this deque - * @throws NullPointerException if the specified array is null - */ - public <T> T[] toArray(T[] a) { - lock.lock(); - try { - if (a.length < count) - a = (T[])java.lang.reflect.Array.newInstance( - a.getClass().getComponentType(), - count - ); - - int k = 0; - for (Node<E> p = first; p != null; p = p.next) - a[k++] = (T)p.item; - if (a.length > k) - a[k] = null; - return a; - } finally { - lock.unlock(); - } - } - - public String toString() { - lock.lock(); - try { - return super.toString(); - } finally { - lock.unlock(); - } - } - - /** - * Atomically removes all of the elements from this deque. - * The deque will be empty after this call returns. - */ - public void clear() { - lock.lock(); - try { - first = last = null; - count = 0; - notFull.signalAll(); - } finally { - lock.unlock(); - } - } - - /** - * Returns an iterator over the elements in this deque in proper sequence. - * The elements will be returned in order from first (head) to last (tail). - * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that - * will never throw {@link 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. - * - * @return an iterator over the elements in this deque in proper sequence - */ - public Iterator<E> iterator() { - return new Itr(); - } - - /** - * Returns an iterator over the elements in this deque in reverse - * sequential order. The elements will be returned in order from - * last (tail) to first (head). - * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that - * will never throw {@link 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. - */ - public Iterator<E> descendingIterator() { - return new DescendingItr(); - } - - /** - * Base class for Iterators for LinkedBlockingDeque - */ - private abstract class AbstractItr implements Iterator<E> { - /** - * The next node to return in next - */ - Node<E> next; - - /** - * nextItem holds on to item fields because once we claim that - * an element exists in hasNext(), we must return item read - * under lock (in advance()) even if it was in the process of - * being removed when hasNext() was called. - */ - E nextItem; - - /** - * Node returned by most recent call to next. Needed by remove. - * Reset to null if this element is deleted by a call to remove. - */ - private Node<E> lastRet; - - AbstractItr() { - advance(); // set to initial position - } - - /** - * Advances next, or if not yet initialized, sets to first node. - * Implemented to move forward vs backward in the two subclasses. - */ - abstract void advance(); - - public boolean hasNext() { - return next != null; - } - - public E next() { - if (next == null) - throw new NoSuchElementException(); - lastRet = next; - E x = nextItem; - advance(); - return x; - } - - public void remove() { - Node<E> n = lastRet; - if (n == null) - throw new IllegalStateException(); - lastRet = null; - // Note: removeNode rescans looking for this node to make - // sure it was not already removed. Otherwise, trying to - // re-remove could corrupt list. - removeNode(n); - } - } - - /** Forward iterator */ - private class Itr extends AbstractItr { - void advance() { - final ReentrantLock lock = LinkedBlockingDeque.this.lock; - lock.lock(); - try { - next = (next == null)? first : next.next; - nextItem = (next == null)? null : next.item; - } finally { - lock.unlock(); - } - } - } - - /** - * Descending iterator for LinkedBlockingDeque - */ - private class DescendingItr extends AbstractItr { - void advance() { - final ReentrantLock lock = LinkedBlockingDeque.this.lock; - lock.lock(); - try { - next = (next == null)? last : next.prev; - nextItem = (next == null)? null : next.item; - } finally { - lock.unlock(); - } - } - } - - /** - * Save the state of this deque to a stream (that is, serialize it). - * - * @serialData The capacity (int), followed by elements (each an - * <tt>Object</tt>) in the proper order, followed by a null - * @param s the stream - */ - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - lock.lock(); - try { - // Write out capacity and any hidden stuff - s.defaultWriteObject(); - // Write out all elements in the proper order. - for (Node<E> p = first; p != null; p = p.next) - s.writeObject(p.item); - // Use trailing null as sentinel - s.writeObject(null); - } finally { - lock.unlock(); - } - } - - /** - * Reconstitute this deque from a stream (that is, - * deserialize it). - * @param s the stream - */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); - count = 0; - first = null; - last = null; - // Read in all elements and place in queue - for (;;) { - E item = (E)s.readObject(); - if (item == null) - break; - add(item); - } - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingQueue.java deleted file mode 100644 index 6201809..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingQueue.java +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.atomic.*; -import java.util.concurrent.locks.*; -import java.util.*; - -/** - * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on - * linked nodes. - * This queue orders elements FIFO (first-in-first-out). - * The <em>head</em> of the queue is that element that has been on the - * queue the longest time. - * The <em>tail</em> of the queue is that element that has been on the - * queue the shortest time. New elements - * are inserted at the tail of the queue, and the queue retrieval - * operations obtain elements at the head of the queue. - * Linked queues typically have higher throughput than array-based queues but - * less predictable performance in most concurrent applications. - * - * <p> The optional capacity bound constructor argument serves as a - * way to prevent excessive queue expansion. The capacity, if unspecified, - * is equal to {@link Integer#MAX_VALUE}. Linked nodes are - * dynamically created upon each insertion unless this would bring the - * queue above capacity. - * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - * - */ -public class LinkedBlockingQueue<E> extends AbstractQueue<E> - implements BlockingQueue<E>, java.io.Serializable { - private static final long serialVersionUID = -6903933977591709194L; - - /* - * A variant of the "two lock queue" algorithm. The putLock gates - * entry to put (and offer), and has an associated condition for - * waiting puts. Similarly for the takeLock. The "count" field - * that they both rely on is maintained as an atomic to avoid - * needing to get both locks in most cases. Also, to minimize need - * for puts to get takeLock and vice-versa, cascading notifies are - * used. When a put notices that it has enabled at least one take, - * it signals taker. That taker in turn signals others if more - * items have been entered since the signal. And symmetrically for - * takes signalling puts. Operations such as remove(Object) and - * iterators acquire both locks. - */ - - /** - * Linked list node class - */ - static class Node<E> { - /** The item, volatile to ensure barrier separating write and read */ - volatile E item; - Node<E> next; - Node(E x) { item = x; } - } - - /** The capacity bound, or Integer.MAX_VALUE if none */ - private final int capacity; - - /** Current number of elements */ - private final AtomicInteger count = new AtomicInteger(0); - - /** Head of linked list */ - private transient Node<E> head; - - /** Tail of linked list */ - private transient Node<E> last; - - /** Lock held by take, poll, etc */ - private final ReentrantLock takeLock = new ReentrantLock(); - - /** Wait queue for waiting takes */ - private final Condition notEmpty = takeLock.newCondition(); - - /** Lock held by put, offer, etc */ - private final ReentrantLock putLock = new ReentrantLock(); - - /** Wait queue for waiting puts */ - private final Condition notFull = putLock.newCondition(); - - /** - * Signals a waiting take. Called only from put/offer (which do not - * otherwise ordinarily lock takeLock.) - */ - private void signalNotEmpty() { - final ReentrantLock takeLock = this.takeLock; - takeLock.lock(); - try { - notEmpty.signal(); - } finally { - takeLock.unlock(); - } - } - - /** - * Signals a waiting put. Called only from take/poll. - */ - private void signalNotFull() { - final ReentrantLock putLock = this.putLock; - putLock.lock(); - try { - notFull.signal(); - } finally { - putLock.unlock(); - } - } - - /** - * Creates a node and links it at end of queue. - * @param x the item - */ - private void insert(E x) { - last = last.next = new Node<E>(x); - } - - /** - * Removes a node from head of queue, - * @return the node - */ - private E extract() { - Node<E> first = head.next; - head = first; - E x = first.item; - first.item = null; - return x; - } - - /** - * Lock to prevent both puts and takes. - */ - private void fullyLock() { - putLock.lock(); - takeLock.lock(); - } - - /** - * Unlock to allow both puts and takes. - */ - private void fullyUnlock() { - takeLock.unlock(); - putLock.unlock(); - } - - - /** - * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of - * {@link Integer#MAX_VALUE}. - */ - public LinkedBlockingQueue() { - this(Integer.MAX_VALUE); - } - - /** - * Creates a <tt>LinkedBlockingQueue</tt> with the given (fixed) capacity. - * - * @param capacity the capacity of this queue - * @throws IllegalArgumentException if <tt>capacity</tt> is not greater - * than zero - */ - public LinkedBlockingQueue(int capacity) { - if (capacity <= 0) throw new IllegalArgumentException(); - this.capacity = capacity; - last = head = new Node<E>(null); - } - - /** - * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of - * {@link Integer#MAX_VALUE}, initially containing the elements of the - * given collection, - * added in traversal order of the collection's iterator. - * - * @param c the collection of elements to initially contain - * @throws NullPointerException if the specified collection or any - * of its elements are null - */ - public LinkedBlockingQueue(Collection<? extends E> c) { - this(Integer.MAX_VALUE); - for (E e : c) - add(e); - } - - - // this doc comment is overridden to remove the reference to collections - // greater in size than Integer.MAX_VALUE - /** - * Returns the number of elements in this queue. - * - * @return the number of elements in this queue - */ - public int size() { - return count.get(); - } - - // this doc comment is a modified copy of the inherited doc comment, - // without the reference to unlimited queues. - /** - * Returns the number of additional 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 <tt>size</tt> of this queue. - * - * <p>Note that you <em>cannot</em> always tell if an attempt to insert - * an element will succeed by inspecting <tt>remainingCapacity</tt> - * because it may be the case that another thread is about to - * insert or remove an element. - */ - public int remainingCapacity() { - return capacity - count.get(); - } - - /** - * Inserts the specified element at the tail of this queue, waiting if - * necessary for space to become available. - * - * @throws InterruptedException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public void put(E e) throws InterruptedException { - if (e == null) throw new NullPointerException(); - // Note: convention in all put/take/etc is to preset - // local var holding count negative to indicate failure unless set. - int c = -1; - final ReentrantLock putLock = this.putLock; - final AtomicInteger count = this.count; - putLock.lockInterruptibly(); - try { - /* - * Note that count is used in wait guard even though it is - * not protected by lock. This works because count can - * only decrease at this point (all other puts are shut - * out by lock), and we (or some other waiting put) are - * signalled if it ever changes from - * capacity. Similarly for all other uses of count in - * other wait guards. - */ - try { - while (count.get() == capacity) - notFull.await(); - } catch (InterruptedException ie) { - notFull.signal(); // propagate to a non-interrupted thread - throw ie; - } - insert(e); - c = count.getAndIncrement(); - if (c + 1 < capacity) - notFull.signal(); - } finally { - putLock.unlock(); - } - if (c == 0) - signalNotEmpty(); - } - - /** - * Inserts the specified element at the tail of this queue, waiting if - * necessary up to the specified wait time for space to become available. - * - * @return <tt>true</tt> if successful, or <tt>false</tt> if - * the specified waiting time elapses before space is available. - * @throws InterruptedException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public boolean offer(E e, long timeout, TimeUnit unit) - throws InterruptedException { - - if (e == null) throw new NullPointerException(); - long nanos = unit.toNanos(timeout); - int c = -1; - final ReentrantLock putLock = this.putLock; - final AtomicInteger count = this.count; - putLock.lockInterruptibly(); - try { - for (;;) { - if (count.get() < capacity) { - insert(e); - c = count.getAndIncrement(); - if (c + 1 < capacity) - notFull.signal(); - break; - } - if (nanos <= 0) - return false; - try { - nanos = notFull.awaitNanos(nanos); - } catch (InterruptedException ie) { - notFull.signal(); // propagate to a non-interrupted thread - throw ie; - } - } - } finally { - putLock.unlock(); - } - if (c == 0) - signalNotEmpty(); - return true; - } - - /** - * Inserts the specified element at the tail of this queue if it is - * possible to do so immediately without exceeding the queue's capacity, - * returning <tt>true</tt> upon success and <tt>false</tt> if this queue - * is full. - * When using a capacity-restricted queue, this method is generally - * preferable to method {@link BlockingQueue#add add}, which can fail to - * insert an element only by throwing an exception. - * - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e) { - if (e == null) throw new NullPointerException(); - final AtomicInteger count = this.count; - if (count.get() == capacity) - return false; - int c = -1; - final ReentrantLock putLock = this.putLock; - putLock.lock(); - try { - if (count.get() < capacity) { - insert(e); - c = count.getAndIncrement(); - if (c + 1 < capacity) - notFull.signal(); - } - } finally { - putLock.unlock(); - } - if (c == 0) - signalNotEmpty(); - return c >= 0; - } - - - public E take() throws InterruptedException { - E x; - int c = -1; - final AtomicInteger count = this.count; - final ReentrantLock takeLock = this.takeLock; - takeLock.lockInterruptibly(); - try { - try { - while (count.get() == 0) - notEmpty.await(); - } catch (InterruptedException ie) { - notEmpty.signal(); // propagate to a non-interrupted thread - throw ie; - } - - x = extract(); - c = count.getAndDecrement(); - if (c > 1) - notEmpty.signal(); - } finally { - takeLock.unlock(); - } - if (c == capacity) - signalNotFull(); - return x; - } - - public E poll(long timeout, TimeUnit unit) throws InterruptedException { - E x = null; - int c = -1; - long nanos = unit.toNanos(timeout); - final AtomicInteger count = this.count; - final ReentrantLock takeLock = this.takeLock; - takeLock.lockInterruptibly(); - try { - for (;;) { - if (count.get() > 0) { - x = extract(); - c = count.getAndDecrement(); - if (c > 1) - notEmpty.signal(); - break; - } - if (nanos <= 0) - return null; - try { - nanos = notEmpty.awaitNanos(nanos); - } catch (InterruptedException ie) { - notEmpty.signal(); // propagate to a non-interrupted thread - throw ie; - } - } - } finally { - takeLock.unlock(); - } - if (c == capacity) - signalNotFull(); - return x; - } - - public E poll() { - final AtomicInteger count = this.count; - if (count.get() == 0) - return null; - E x = null; - int c = -1; - final ReentrantLock takeLock = this.takeLock; - takeLock.lock(); - try { - if (count.get() > 0) { - x = extract(); - c = count.getAndDecrement(); - if (c > 1) - notEmpty.signal(); - } - } finally { - takeLock.unlock(); - } - if (c == capacity) - signalNotFull(); - return x; - } - - - public E peek() { - if (count.get() == 0) - return null; - final ReentrantLock takeLock = this.takeLock; - takeLock.lock(); - try { - Node<E> first = head.next; - if (first == null) - return null; - else - return first.item; - } finally { - takeLock.unlock(); - } - } - - /** - * Removes a single instance of the specified element from this queue, - * if it is present. More formally, removes an element <tt>e</tt> such - * that <tt>o.equals(e)</tt>, if this queue contains one or more such - * elements. - * Returns <tt>true</tt> if this queue contained the specified element - * (or equivalently, if this queue changed as a result of the call). - * - * @param o element to be removed from this queue, if present - * @return <tt>true</tt> if this queue changed as a result of the call - */ - public boolean remove(Object o) { - if (o == null) return false; - boolean removed = false; - fullyLock(); - try { - Node<E> trail = head; - Node<E> p = head.next; - while (p != null) { - if (o.equals(p.item)) { - removed = true; - break; - } - trail = p; - p = p.next; - } - if (removed) { - p.item = null; - trail.next = p.next; - if (last == p) - last = trail; - if (count.getAndDecrement() == capacity) - notFull.signalAll(); - } - } finally { - fullyUnlock(); - } - return removed; - } - - /** - * Returns an array containing all of the elements in this queue, in - * proper sequence. - * - * <p>The returned array will be "safe" in that no references to it are - * maintained by this queue. (In other words, this method must allocate - * a new array). The caller is thus free to modify the returned array. - * - * <p>This method acts as bridge between array-based and collection-based - * APIs. - * - * @return an array containing all of the elements in this queue - */ - public Object[] toArray() { - fullyLock(); - try { - int size = count.get(); - Object[] a = new Object[size]; - int k = 0; - for (Node<E> p = head.next; p != null; p = p.next) - a[k++] = p.item; - return a; - } finally { - fullyUnlock(); - } - } - - /** - * Returns an array containing all of the elements in this queue, in - * proper sequence; the runtime type of the returned array is that of - * the specified array. If the queue fits in the specified array, it - * is returned therein. Otherwise, a new array is allocated with the - * runtime type of the specified array and the size of this queue. - * - * <p>If this queue fits in the specified array with room to spare - * (i.e., the array has more elements than this queue), the element in - * the array immediately following the end of the queue is set to - * <tt>null</tt>. - * - * <p>Like the {@link #toArray()} method, this method acts as bridge between - * array-based and collection-based APIs. Further, this method allows - * precise control over the runtime type of the output array, and may, - * under certain circumstances, be used to save allocation costs. - * - * <p>Suppose <tt>x</tt> is a queue known to contain only strings. - * The following code can be used to dump the queue into a newly - * allocated array of <tt>String</tt>: - * - * <pre> - * String[] y = x.toArray(new String[0]);</pre> - * - * Note that <tt>toArray(new Object[0])</tt> is identical in function to - * <tt>toArray()</tt>. - * - * @param a the array into which the elements of the queue are to - * be stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose - * @return an array containing all of the elements in this queue - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in - * this queue - * @throws NullPointerException if the specified array is null - */ - public <T> T[] toArray(T[] a) { - fullyLock(); - try { - int size = count.get(); - if (a.length < size) - a = (T[])java.lang.reflect.Array.newInstance - (a.getClass().getComponentType(), size); - - int k = 0; - for (Node p = head.next; p != null; p = p.next) - a[k++] = (T)p.item; - if (a.length > k) - a[k] = null; - return a; - } finally { - fullyUnlock(); - } - } - - public String toString() { - fullyLock(); - try { - return super.toString(); - } finally { - fullyUnlock(); - } - } - - /** - * Atomically removes all of the elements from this queue. - * The queue will be empty after this call returns. - */ - public void clear() { - fullyLock(); - try { - head.next = null; - assert head.item == null; - last = head; - if (count.getAndSet(0) == capacity) - notFull.signalAll(); - } finally { - fullyUnlock(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - Node<E> first; - fullyLock(); - try { - first = head.next; - head.next = null; - assert head.item == null; - last = head; - if (count.getAndSet(0) == capacity) - notFull.signalAll(); - } finally { - fullyUnlock(); - } - // Transfer the elements outside of locks - int n = 0; - for (Node<E> p = first; p != null; p = p.next) { - c.add(p.item); - p.item = null; - ++n; - } - return n; - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c, int maxElements) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - fullyLock(); - try { - int n = 0; - Node<E> p = head.next; - while (p != null && n < maxElements) { - c.add(p.item); - p.item = null; - p = p.next; - ++n; - } - if (n != 0) { - head.next = p; - assert head.item == null; - if (p == null) - last = head; - if (count.getAndAdd(-n) == capacity) - notFull.signalAll(); - } - return n; - } finally { - fullyUnlock(); - } - } - - /** - * Returns an iterator over the elements in this queue in proper sequence. - * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that - * will never throw {@link 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. - * - * @return an iterator over the elements in this queue in proper sequence - */ - public Iterator<E> iterator() { - return new Itr(); - } - - private class Itr implements Iterator<E> { - /* - * Basic weak-consistent iterator. At all times hold the next - * item to hand out so that if hasNext() reports true, we will - * still have it to return even if lost race with a take etc. - */ - private Node<E> current; - private Node<E> lastRet; - private E currentElement; - - Itr() { - final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; - final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; - putLock.lock(); - takeLock.lock(); - try { - current = head.next; - if (current != null) - currentElement = current.item; - } finally { - takeLock.unlock(); - putLock.unlock(); - } - } - - public boolean hasNext() { - return current != null; - } - - public E next() { - final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; - final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; - putLock.lock(); - takeLock.lock(); - try { - if (current == null) - throw new NoSuchElementException(); - E x = currentElement; - lastRet = current; - current = current.next; - if (current != null) - currentElement = current.item; - return x; - } finally { - takeLock.unlock(); - putLock.unlock(); - } - } - - public void remove() { - if (lastRet == null) - throw new IllegalStateException(); - final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; - final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; - putLock.lock(); - takeLock.lock(); - try { - Node<E> node = lastRet; - lastRet = null; - Node<E> trail = head; - Node<E> p = head.next; - while (p != null && p != node) { - trail = p; - p = p.next; - } - if (p == node) { - p.item = null; - trail.next = p.next; - if (last == p) - last = trail; - int c = count.getAndDecrement(); - if (c == capacity) - notFull.signalAll(); - } - } finally { - takeLock.unlock(); - putLock.unlock(); - } - } - } - - /** - * Save the state to a stream (that is, serialize it). - * - * @serialData The capacity is emitted (int), followed by all of - * its elements (each an <tt>Object</tt>) in the proper order, - * followed by a null - * @param s the stream - */ - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - - fullyLock(); - try { - // Write out any hidden stuff, plus capacity - s.defaultWriteObject(); - - // Write out all elements in the proper order. - for (Node<E> p = head.next; p != null; p = p.next) - s.writeObject(p.item); - - // Use trailing null as sentinel - s.writeObject(null); - } finally { - fullyUnlock(); - } - } - - /** - * Reconstitute this queue instance from a stream (that is, - * deserialize it). - * @param s the stream - */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - // Read in capacity, and any hidden stuff - s.defaultReadObject(); - - count.set(0); - last = head = new Node<E>(null); - - // Read in all elements and place in queue - for (;;) { - E item = (E)s.readObject(); - if (item == null) - break; - add(item); - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/PriorityBlockingQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/PriorityBlockingQueue.java deleted file mode 100644 index 9466aa4..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/PriorityBlockingQueue.java +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -import java.util.concurrent.locks.*; -import java.util.*; - -/** - * An unbounded {@linkplain BlockingQueue blocking queue} that uses - * the same ordering rules as class {@link PriorityQueue} and supplies - * blocking retrieval operations. While this queue is logically - * unbounded, attempted additions may fail due to resource exhaustion - * (causing <tt>OutOfMemoryError</tt>). This class does not permit - * <tt>null</tt> elements. A priority queue relying on {@linkplain - * Comparable natural ordering} also does not permit insertion of - * non-comparable objects (doing so results in - * <tt>ClassCastException</tt>). - * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. The Iterator provided in method {@link - * #iterator()} is <em>not</em> guaranteed to traverse the elements of - * the PriorityBlockingQueue in any particular order. If you need - * ordered traversal, consider using - * <tt>Arrays.sort(pq.toArray())</tt>. Also, method <tt>drainTo</tt> - * can be used to <em>remove</em> some or all elements in priority - * order and place them in another collection. - * - * <p>Operations on this class make no guarantees about the ordering - * of elements with equal priority. If you need to enforce an - * ordering, you can define custom classes or comparators that use a - * secondary key to break ties in primary priority values. For - * example, here is a class that applies first-in-first-out - * tie-breaking to comparable elements. To use it, you would insert a - * <tt>new FIFOEntry(anEntry)</tt> instead of a plain entry object. - * - * <pre> - * class FIFOEntry<E extends Comparable<? super E>> - * implements Comparable<FIFOEntry<E>> { - * final static AtomicLong seq = new AtomicLong(); - * final long seqNum; - * final E entry; - * public FIFOEntry(E entry) { - * seqNum = seq.getAndIncrement(); - * this.entry = entry; - * } - * public E getEntry() { return entry; } - * public int compareTo(FIFOEntry<E> other) { - * int res = entry.compareTo(other.entry); - * if (res == 0 && other.entry != this.entry) - * res = (seqNum < other.seqNum ? -1 : 1); - * return res; - * } - * }</pre> - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea - * @param <E> the type of elements held in this collection - */ -public class PriorityBlockingQueue<E> extends AbstractQueue<E> - implements BlockingQueue<E>, java.io.Serializable { - private static final long serialVersionUID = 5595510919245408276L; - - private final PriorityQueue<E> q; - private final ReentrantLock lock = new ReentrantLock(true); - private final Condition notEmpty = lock.newCondition(); - - /** - * Creates a <tt>PriorityBlockingQueue</tt> with the default - * initial capacity (11) that orders its elements according to - * their {@linkplain Comparable natural ordering}. - */ - public PriorityBlockingQueue() { - q = new PriorityQueue<E>(); - } - - /** - * Creates a <tt>PriorityBlockingQueue</tt> with the specified - * initial capacity that orders its elements according to their - * {@linkplain Comparable natural ordering}. - * - * @param initialCapacity the initial capacity for this priority queue - * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less - * than 1 - */ - public PriorityBlockingQueue(int initialCapacity) { - q = new PriorityQueue<E>(initialCapacity, null); - } - - /** - * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial - * capacity that orders its elements according to the specified - * comparator. - * - * @param initialCapacity the initial capacity for this priority queue - * @param comparator the comparator that will be used to order this - * priority queue. If {@code null}, the {@linkplain Comparable - * natural ordering} of the elements will be used. - * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less - * than 1 - */ - public PriorityBlockingQueue(int initialCapacity, - Comparator<? super E> comparator) { - q = new PriorityQueue<E>(initialCapacity, comparator); - } - - /** - * Creates a <tt>PriorityBlockingQueue</tt> containing the elements - * in the specified collection. If the specified collection is a - * {@link SortedSet} or a {@link PriorityQueue}, this - * priority queue will be ordered according to the same ordering. - * Otherwise, this priority queue will be ordered according to the - * {@linkplain Comparable natural ordering} of its elements. - * - * @param c the collection whose elements are to be placed - * into this priority queue - * @throws ClassCastException if elements of the specified collection - * cannot be compared to one another according to the priority - * queue's ordering - * @throws NullPointerException if the specified collection or any - * of its elements are null - */ - public PriorityBlockingQueue(Collection<? extends E> c) { - q = new PriorityQueue<E>(c); - } - - /** - * Inserts the specified element into this priority queue. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) - * @throws ClassCastException if the specified element cannot be compared - * with elements currently in the priority queue according to the - * priority queue's ordering - * @throws NullPointerException if the specified element is null - */ - public boolean add(E e) { - return offer(e); - } - - /** - * Inserts the specified element into this priority queue. - * - * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Queue#offer}) - * @throws ClassCastException if the specified element cannot be compared - * with elements currently in the priority queue according to the - * priority queue's ordering - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e) { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - boolean ok = q.offer(e); - assert ok; - notEmpty.signal(); - return true; - } finally { - lock.unlock(); - } - } - - /** - * Inserts the specified element into this priority queue. As the queue is - * unbounded this method will never block. - * - * @param e the element to add - * @throws ClassCastException if the specified element cannot be compared - * with elements currently in the priority queue according to the - * priority queue's ordering - * @throws NullPointerException if the specified element is null - */ - public void put(E e) { - offer(e); // never need to block - } - - /** - * Inserts the specified element into this priority queue. As the queue is - * unbounded this method will never block. - * - * @param e the element to add - * @param timeout This parameter is ignored as the method never blocks - * @param unit This parameter is ignored as the method never blocks - * @return <tt>true</tt> - * @throws ClassCastException if the specified element cannot be compared - * with elements currently in the priority queue according to the - * priority queue's ordering - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e, long timeout, TimeUnit unit) { - return offer(e); // never need to block - } - - public E poll() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.poll(); - } finally { - lock.unlock(); - } - } - - public E take() throws InterruptedException { - final ReentrantLock lock = this.lock; - lock.lockInterruptibly(); - try { - try { - while (q.size() == 0) - notEmpty.await(); - } catch (InterruptedException ie) { - notEmpty.signal(); // propagate to non-interrupted thread - throw ie; - } - E x = q.poll(); - assert x != null; - return x; - } finally { - lock.unlock(); - } - } - - public E poll(long timeout, TimeUnit unit) throws InterruptedException { - long nanos = unit.toNanos(timeout); - final ReentrantLock lock = this.lock; - lock.lockInterruptibly(); - try { - for (;;) { - E x = q.poll(); - if (x != null) - 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 E peek() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.peek(); - } finally { - lock.unlock(); - } - } - - /** - * Returns the comparator used to order the elements in this queue, - * or <tt>null</tt> if this queue uses the {@linkplain Comparable - * natural ordering} of its elements. - * - * @return the comparator used to order the elements in this queue, - * or <tt>null</tt> if this queue uses the natural - * ordering of its elements - */ - public Comparator<? super E> comparator() { - return q.comparator(); - } - - public int size() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.size(); - } finally { - lock.unlock(); - } - } - - /** - * Always returns <tt>Integer.MAX_VALUE</tt> because - * a <tt>PriorityBlockingQueue</tt> is not capacity constrained. - * @return <tt>Integer.MAX_VALUE</tt> - */ - public int remainingCapacity() { - return Integer.MAX_VALUE; - } - - /** - * Removes a single instance of the specified element from this queue, - * if it is present. More formally, removes an element {@code e} such - * that {@code o.equals(e)}, if this queue contains one or more such - * elements. Returns {@code true} if and only if this queue contained - * the specified element (or equivalently, if this queue changed as a - * result of the call). - * - * @param o element to be removed from this queue, if present - * @return <tt>true</tt> if this queue changed as a result of the call - */ - public boolean remove(Object o) { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.remove(o); - } finally { - lock.unlock(); - } - } - - /** - * Returns {@code true} if this queue contains the specified element. - * More formally, returns {@code true} if and only if this queue contains - * at least one element {@code e} such that {@code o.equals(e)}. - * - * @param o object to be checked for containment in this queue - * @return <tt>true</tt> if this queue contains the specified element - */ - public boolean contains(Object o) { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.contains(o); - } finally { - lock.unlock(); - } - } - - /** - * Returns an array containing all of the elements in this queue. - * The returned array elements are in no particular order. - * - * <p>The returned array will be "safe" in that no references to it are - * maintained by this queue. (In other words, this method must allocate - * a new array). The caller is thus free to modify the returned array. - * - * <p>This method acts as bridge between array-based and collection-based - * APIs. - * - * @return an array containing all of the elements in this queue - */ - public Object[] toArray() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.toArray(); - } finally { - lock.unlock(); - } - } - - - public String toString() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.toString(); - } finally { - lock.unlock(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - final ReentrantLock lock = this.lock; - lock.lock(); - try { - int n = 0; - E e; - while ( (e = q.poll()) != null) { - c.add(e); - ++n; - } - return n; - } finally { - lock.unlock(); - } - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c, int maxElements) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - if (maxElements <= 0) - return 0; - final ReentrantLock lock = this.lock; - lock.lock(); - try { - int n = 0; - E e; - while (n < maxElements && (e = q.poll()) != null) { - c.add(e); - ++n; - } - return n; - } finally { - lock.unlock(); - } - } - - /** - * Atomically removes all of the elements from this queue. - * The queue will be empty after this call returns. - */ - public void clear() { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - q.clear(); - } finally { - lock.unlock(); - } - } - - /** - * Returns an array containing all of the elements in this queue; the - * runtime type of the returned array is that of the specified array. - * The returned array elements are in no particular order. - * If the queue fits in the specified array, it is returned therein. - * Otherwise, a new array is allocated with the runtime type of the - * specified array and the size of this queue. - * - * <p>If this queue fits in the specified array with room to spare - * (i.e., the array has more elements than this queue), the element in - * the array immediately following the end of the queue is set to - * <tt>null</tt>. - * - * <p>Like the {@link #toArray()} method, this method acts as bridge between - * array-based and collection-based APIs. Further, this method allows - * precise control over the runtime type of the output array, and may, - * under certain circumstances, be used to save allocation costs. - * - * <p>Suppose <tt>x</tt> is a queue known to contain only strings. - * The following code can be used to dump the queue into a newly - * allocated array of <tt>String</tt>: - * - * <pre> - * String[] y = x.toArray(new String[0]);</pre> - * - * Note that <tt>toArray(new Object[0])</tt> is identical in function to - * <tt>toArray()</tt>. - * - * @param a the array into which the elements of the queue are to - * be stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose - * @return an array containing all of the elements in this queue - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in - * this queue - * @throws NullPointerException if the specified array is null - */ - public <T> T[] toArray(T[] a) { - final ReentrantLock lock = this.lock; - lock.lock(); - try { - return q.toArray(a); - } finally { - lock.unlock(); - } - } - - /** - * Returns an iterator over the elements in this queue. The - * iterator does not return the elements in any particular order. - * The returned <tt>Iterator</tt> is a "weakly consistent" - * iterator that will never throw {@link - * 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. - * - * @return an iterator over the elements in this queue - */ - public Iterator<E> iterator() { - return new Itr(toArray()); - } - - /** - * Snapshot iterator that works off copy of underlying q array. - */ - private class Itr implements Iterator<E> { - final Object[] array; // Array of all elements - int cursor; // index of next element to return; - int lastRet; // index of last element, or -1 if no such - - Itr(Object[] array) { - lastRet = -1; - this.array = array; - } - - public boolean hasNext() { - return cursor < array.length; - } - - public E next() { - if (cursor >= array.length) - throw new NoSuchElementException(); - lastRet = cursor; - return (E)array[cursor++]; - } - - public void remove() { - if (lastRet < 0) - throw new IllegalStateException(); - Object x = array[lastRet]; - lastRet = -1; - // Traverse underlying queue to find == element, - // not just a .equals element. - lock.lock(); - try { - for (Iterator it = q.iterator(); it.hasNext(); ) { - if (it.next() == x) { - it.remove(); - return; - } - } - } finally { - lock.unlock(); - } - } - } - - /** - * Saves the state to a stream (that is, serializes it). This - * merely wraps default serialization within lock. The - * serialization strategy for items is left to underlying - * Queue. Note that locking is not needed on deserialization, so - * readObject is not defined, just relying on default. - */ - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - lock.lock(); - try { - s.defaultWriteObject(); - } finally { - lock.unlock(); - } - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionException.java b/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionException.java deleted file mode 100644 index 30b043d..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionException.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * Exception thrown by an {@link Executor} when a task cannot be - * accepted for execution. - * - * @since 1.5 - * @author Doug Lea - */ -public class RejectedExecutionException extends RuntimeException { - private static final long serialVersionUID = -375805702767069545L; - - /** - * Constructs a <tt>RejectedExecutionException</tt> with no detail message. - * The cause is not initialized, and may subsequently be - * initialized by a call to {@link #initCause(Throwable) initCause}. - */ - public RejectedExecutionException() { } - - /** - * Constructs a <tt>RejectedExecutionException</tt> with the - * specified detail message. The cause is not initialized, and may - * subsequently be initialized by a call to {@link - * #initCause(Throwable) initCause}. - * - * @param message the detail message - */ - public RejectedExecutionException(String message) { - super(message); - } - - /** - * Constructs a <tt>RejectedExecutionException</tt> with the - * specified detail message and cause. - * - * @param message the detail message - * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method) - */ - public RejectedExecutionException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a <tt>RejectedExecutionException</tt> with the - * specified cause. The detail message is set to: <pre> (cause == - * null ? null : cause.toString())</pre> (which typically contains - * the class and detail message of <tt>cause</tt>). - * - * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method) - */ - public RejectedExecutionException(Throwable cause) { - super(cause); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionHandler.java b/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionHandler.java deleted file mode 100644 index 4b4bbea..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A handler for tasks that cannot be executed by a {@link - * ThreadPoolExecutor}. - * - * @since 1.5 - * @author Doug Lea - */ -public interface RejectedExecutionHandler { - - /** - * Method that may be invoked by a {@link ThreadPoolExecutor} when - * <tt>execute</tt> cannot accept a task. This may occur when no - * more threads or queue slots are available because their bounds - * would be exceeded, or upon shutdown of the Executor. - * - * In the absence other alternatives, the method may throw an - * unchecked {@link RejectedExecutionException}, which will be - * propagated to the caller of <tt>execute</tt>. - * - * @param r the runnable task requested to be executed - * @param executor the executor attempting to execute this task - * @throws RejectedExecutionException if there is no remedy - */ - void rejectedExecution(Runnable r, ThreadPoolExecutor executor); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/RunnableFuture.java b/libjava/classpath/external/jsr166/java/util/concurrent/RunnableFuture.java deleted file mode 100644 index d74211d..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/RunnableFuture.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A {@link Future} that is {@link Runnable}. Successful execution of - * the <tt>run</tt> method causes completion of the <tt>Future</tt> - * and allows access to its results. - * @see FutureTask - * @see Executor - * @since 1.6 - * @author Doug Lea - * @param <V> The result type returned by this Future's <tt>get</tt> method - */ -public interface RunnableFuture<V> extends Runnable, Future<V> { - /** - * Sets this Future to the result of its computation - * unless it has been cancelled. - */ - void run(); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/RunnableScheduledFuture.java b/libjava/classpath/external/jsr166/java/util/concurrent/RunnableScheduledFuture.java deleted file mode 100644 index 0e8cc32..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/RunnableScheduledFuture.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A {@link ScheduledFuture} that is {@link Runnable}. Successful - * execution of the <tt>run</tt> method causes completion of the - * <tt>Future</tt> and allows access to its results. - * @see FutureTask - * @see Executor - * @since 1.6 - * @author Doug Lea - * @param <V> The result type returned by this Future's <tt>get</tt> method - */ -public interface RunnableScheduledFuture<V> extends RunnableFuture<V>, ScheduledFuture<V> { - - /** - * Returns true if this is a periodic task. A periodic task may - * re-run according to some schedule. A non-periodic task can be - * run only once. - * - * @return true if this task is periodic - */ - boolean isPeriodic(); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledExecutorService.java b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledExecutorService.java deleted file mode 100644 index c170c4a..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledExecutorService.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.atomic.*; -import java.util.*; - -/** - * An {@link ExecutorService} that can schedule commands to run after a given - * delay, or to execute periodically. - * - * <p> The <tt>schedule</tt> methods create tasks with various delays - * and return a task object that can be used to cancel or check - * execution. The <tt>scheduleAtFixedRate</tt> and - * <tt>scheduleWithFixedDelay</tt> methods create and execute tasks - * that run periodically until cancelled. - * - * <p> Commands submitted using the {@link Executor#execute} and - * {@link ExecutorService} <tt>submit</tt> methods are scheduled with - * a requested delay of zero. Zero and negative delays (but not - * periods) are also allowed in <tt>schedule</tt> methods, and are - * treated as requests for immediate execution. - * - * <p>All <tt>schedule</tt> methods accept <em>relative</em> delays and - * periods as arguments, not absolute times or dates. It is a simple - * matter to transform an absolute time represented as a {@link - * java.util.Date} to the required form. For example, to schedule at - * a certain future <tt>date</tt>, you can use: <tt>schedule(task, - * date.getTime() - System.currentTimeMillis(), - * TimeUnit.MILLISECONDS)</tt>. Beware however that expiration of a - * relative delay need not coincide with the current <tt>Date</tt> at - * which the task is enabled due to network time synchronization - * protocols, clock drift, or other factors. - * - * The {@link Executors} class provides convenient factory methods for - * the ScheduledExecutorService implementations provided in this package. - * - * <h3>Usage Example</h3> - * - * Here is a class with a method that sets up a ScheduledExecutorService - * to beep every ten seconds for an hour: - * - * <pre> - * import static java.util.concurrent.TimeUnit.*; - * class BeeperControl { - * private final ScheduledExecutorService scheduler = - * Executors.newScheduledThreadPool(1); - * - * public void beepForAnHour() { - * final Runnable beeper = new Runnable() { - * public void run() { System.out.println("beep"); } - * }; - * final ScheduledFuture<?> beeperHandle = - * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS); - * scheduler.schedule(new Runnable() { - * public void run() { beeperHandle.cancel(true); } - * }, 60 * 60, SECONDS); - * } - * } - * </pre> - * - * @since 1.5 - * @author Doug Lea - */ -public interface ScheduledExecutorService extends ExecutorService { - - /** - * Creates and executes a one-shot action that becomes enabled - * after the given delay. - * - * @param command the task to execute - * @param delay the time from now to delay execution - * @param unit the time unit of the delay parameter - * @return a ScheduledFuture representing pending completion of - * the task and whose <tt>get()</tt> method will return - * <tt>null</tt> upon completion - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if command is null - */ - public ScheduledFuture<?> schedule(Runnable command, - long delay, TimeUnit unit); - - /** - * Creates and executes a ScheduledFuture that becomes enabled after the - * given delay. - * - * @param callable the function to execute - * @param delay the time from now to delay execution - * @param unit the time unit of the delay parameter - * @return a ScheduledFuture that can be used to extract result or cancel - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if callable is null - */ - public <V> ScheduledFuture<V> schedule(Callable<V> callable, - long delay, TimeUnit unit); - - /** - * Creates and executes a periodic action that becomes enabled first - * after the given initial delay, and subsequently with the given - * period; that is executions will commence after - * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then - * <tt>initialDelay + 2 * period</tt>, and so on. - * If any execution of the task - * encounters an exception, subsequent executions are suppressed. - * Otherwise, the task will only terminate via cancellation or - * termination of the executor. If any execution of this task - * takes longer than its period, then subsequent executions - * may start late, but will not concurrently execute. - * - * @param command the task to execute - * @param initialDelay the time to delay first execution - * @param period the period between successive executions - * @param unit the time unit of the initialDelay and period parameters - * @return a ScheduledFuture representing pending completion of - * the task, and whose <tt>get()</tt> method will throw an - * exception upon cancellation - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if command is null - * @throws IllegalArgumentException if period less than or equal to zero - */ - public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, - long initialDelay, - long period, - TimeUnit unit); - - /** - * Creates and executes a periodic action that becomes enabled first - * after the given initial delay, and subsequently with the - * given delay between the termination of one execution and the - * commencement of the next. If any execution of the task - * encounters an exception, subsequent executions are suppressed. - * Otherwise, the task will only terminate via cancellation or - * termination of the executor. - * - * @param command the task to execute - * @param initialDelay the time to delay first execution - * @param delay the delay between the termination of one - * execution and the commencement of the next - * @param unit the time unit of the initialDelay and delay parameters - * @return a ScheduledFuture representing pending completion of - * the task, and whose <tt>get()</tt> method will throw an - * exception upon cancellation - * @throws RejectedExecutionException if the task cannot be - * scheduled for execution - * @throws NullPointerException if command is null - * @throws IllegalArgumentException if delay less than or equal to zero - */ - public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, - long initialDelay, - long delay, - TimeUnit unit); - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledFuture.java b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledFuture.java deleted file mode 100644 index 239d681..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledFuture.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A delayed result-bearing action that can be cancelled. - * Usually a scheduled future is the result of scheduling - * a task with a {@link ScheduledExecutorService}. - * - * @since 1.5 - * @author Doug Lea - * @param <V> The result type returned by this Future - */ -public interface ScheduledFuture<V> extends Delayed, Future<V> { -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledThreadPoolExecutor.java b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledThreadPoolExecutor.java deleted file mode 100644 index f08b9ac..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.atomic.*; -import java.util.*; - -/** - * A {@link ThreadPoolExecutor} that can additionally schedule - * commands to run after a given delay, or to execute - * periodically. This class is preferable to {@link java.util.Timer} - * when multiple worker threads are needed, or when the additional - * flexibility or capabilities of {@link ThreadPoolExecutor} (which - * this class extends) are required. - * - * <p> Delayed tasks execute no sooner than they are enabled, but - * without any real-time guarantees about when, after they are - * enabled, they will commence. Tasks scheduled for exactly the same - * execution time are enabled in first-in-first-out (FIFO) order of - * submission. - * - * <p>While this class inherits from {@link ThreadPoolExecutor}, a few - * of the inherited tuning methods are not useful for it. In - * particular, because it acts as a fixed-sized pool using - * <tt>corePoolSize</tt> threads and an unbounded queue, adjustments - * to <tt>maximumPoolSize</tt> have no useful effect. - * - * <p><b>Extension notes:</b> This class overrides {@link - * AbstractExecutorService} <tt>submit</tt> methods to generate - * internal objects to control per-task delays and scheduling. To - * preserve functionality, any further overrides of these methods in - * subclasses must invoke superclass versions, which effectively - * disables additional task customization. However, this class - * provides alternative protected extension method - * <tt>decorateTask</tt> (one version each for <tt>Runnable</tt> and - * <tt>Callable</tt>) that can be used to customize the concrete task - * types used to execute commands entered via <tt>execute</tt>, - * <tt>submit</tt>, <tt>schedule</tt>, <tt>scheduleAtFixedRate</tt>, - * and <tt>scheduleWithFixedDelay</tt>. By default, a - * <tt>ScheduledThreadPoolExecutor</tt> uses a task type extending - * {@link FutureTask}. However, this may be modified or replaced using - * subclasses of the form: - * - * <pre> - * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor { - * - * static class CustomTask<V> implements RunnableScheduledFuture<V> { ... } - * - * protected <V> RunnableScheduledFuture<V> decorateTask( - * Runnable r, RunnableScheduledFuture<V> task) { - * return new CustomTask<V>(r, task); - * } - * - * protected <V> RunnableScheduledFuture<V> decorateTask( - * Callable<V> c, RunnableScheduledFuture<V> task) { - * return new CustomTask<V>(c, task); - * } - * // ... add constructors, etc. - * } - * </pre> - * @since 1.5 - * @author Doug Lea - */ -public class ScheduledThreadPoolExecutor - extends ThreadPoolExecutor - implements ScheduledExecutorService { - - /** - * False if should cancel/suppress periodic tasks on shutdown. - */ - private volatile boolean continueExistingPeriodicTasksAfterShutdown; - - /** - * False if should cancel non-periodic tasks on shutdown. - */ - private volatile boolean executeExistingDelayedTasksAfterShutdown = true; - - /** - * Sequence number to break scheduling ties, and in turn to - * guarantee FIFO order among tied entries. - */ - private static final AtomicLong sequencer = new AtomicLong(0); - - /** Base of nanosecond timings, to avoid wrapping */ - private static final long NANO_ORIGIN = System.nanoTime(); - - /** - * Returns nanosecond time offset by origin - */ - final long now() { - return System.nanoTime() - NANO_ORIGIN; - } - - private class ScheduledFutureTask<V> - extends FutureTask<V> implements RunnableScheduledFuture<V> { - - /** Sequence number to break ties FIFO */ - private final long sequenceNumber; - /** The time the task is enabled to execute in nanoTime units */ - private long time; - /** - * Period in nanoseconds for repeating tasks. A positive - * value indicates fixed-rate execution. A negative value - * indicates fixed-delay execution. A value of 0 indicates a - * non-repeating task. - */ - private final long period; - - /** - * Creates a one-shot action with given nanoTime-based trigger time. - */ - ScheduledFutureTask(Runnable r, V result, long ns) { - super(r, result); - this.time = ns; - this.period = 0; - this.sequenceNumber = sequencer.getAndIncrement(); - } - - /** - * Creates a periodic action with given nano time and period. - */ - ScheduledFutureTask(Runnable r, V result, long ns, long period) { - super(r, result); - this.time = ns; - this.period = period; - this.sequenceNumber = sequencer.getAndIncrement(); - } - - /** - * Creates a one-shot action with given nanoTime-based trigger. - */ - ScheduledFutureTask(Callable<V> callable, long ns) { - super(callable); - this.time = ns; - this.period = 0; - this.sequenceNumber = sequencer.getAndIncrement(); - } - - public long getDelay(TimeUnit unit) { - long d = unit.convert(time - now(), TimeUnit.NANOSECONDS); - return d; - } - - public int compareTo(Delayed other) { - if (other == this) // compare zero ONLY if same object - return 0; - if (other instanceof ScheduledFutureTask) { - ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other; - long diff = time - x.time; - if (diff < 0) - return -1; - else if (diff > 0) - return 1; - else if (sequenceNumber < x.sequenceNumber) - return -1; - else - return 1; - } - long d = (getDelay(TimeUnit.NANOSECONDS) - - other.getDelay(TimeUnit.NANOSECONDS)); - return (d == 0)? 0 : ((d < 0)? -1 : 1); - } - - /** - * Returns true if this is a periodic (not a one-shot) action. - * - * @return true if periodic - */ - public boolean isPeriodic() { - return period != 0; - } - - /** - * Runs a periodic task. - */ - private void runPeriodic() { - boolean ok = ScheduledFutureTask.super.runAndReset(); - boolean down = isShutdown(); - // Reschedule if not cancelled and not shutdown or policy allows - if (ok && (!down || - (getContinueExistingPeriodicTasksAfterShutdownPolicy() && - !isTerminating()))) { - long p = period; - if (p > 0) - time += p; - else - time = now() - p; - // Classpath local: ecj from eclipse 3.1 does not - // compile this. - // ScheduledThreadPoolExecutor.super.getQueue().add(this); - ScheduledThreadPoolExecutor.super.getQueue().add((Runnable) this); - } - // This might have been the final executed delayed - // task. Wake up threads to check. - else if (down) - interruptIdleWorkers(); - } - - /** - * Overrides FutureTask version so as to reset/requeue if periodic. - */ - public void run() { - if (isPeriodic()) - runPeriodic(); - else - ScheduledFutureTask.super.run(); - } - } - - /** - * Specialized variant of ThreadPoolExecutor.execute for delayed tasks. - */ - private void delayedExecute(Runnable command) { - if (isShutdown()) { - reject(command); - return; - } - // Prestart a thread if necessary. We cannot prestart it - // running the task because the task (probably) shouldn't be - // run yet, so thread will just idle until delay elapses. - if (getPoolSize() < getCorePoolSize()) - prestartCoreThread(); - - super.getQueue().add(command); - } - - /** - * Cancels and clears the queue of all tasks that should not be run - * due to shutdown policy. - */ - private void cancelUnwantedTasks() { - boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy(); - boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy(); - if (!keepDelayed && !keepPeriodic) - super.getQueue().clear(); - else if (keepDelayed || keepPeriodic) { - Object[] entries = super.getQueue().toArray(); - for (int i = 0; i < entries.length; ++i) { - Object e = entries[i]; - if (e instanceof RunnableScheduledFuture) { - RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>)e; - if (t.isPeriodic()? !keepPeriodic : !keepDelayed) - t.cancel(false); - } - } - entries = null; - purge(); - } - } - - public boolean remove(Runnable task) { - if (!(task instanceof RunnableScheduledFuture)) - return false; - return getQueue().remove(task); - } - - /** - * Modifies or replaces the task used to execute a runnable. - * This method can be used to override the concrete - * class used for managing internal tasks. - * The default implementation simply returns the given task. - * - * @param runnable the submitted Runnable - * @param task the task created to execute the runnable - * @return a task that can execute the runnable - * @since 1.6 - */ - protected <V> RunnableScheduledFuture<V> decorateTask( - Runnable runnable, RunnableScheduledFuture<V> task) { - return task; - } - - /** - * Modifies or replaces the task used to execute a callable. - * This method can be used to override the concrete - * class used for managing internal tasks. - * The default implementation simply returns the given task. - * - * @param callable the submitted Callable - * @param task the task created to execute the callable - * @return a task that can execute the callable - * @since 1.6 - */ - protected <V> RunnableScheduledFuture<V> decorateTask( - Callable<V> callable, RunnableScheduledFuture<V> task) { - return task; - } - - /** - * Creates a new ScheduledThreadPoolExecutor with the given core - * pool size. - * - * @param corePoolSize the number of threads to keep in the pool, - * even if they are idle - * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> - */ - public ScheduledThreadPoolExecutor(int corePoolSize) { - super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, - new DelayedWorkQueue()); - } - - /** - * Creates a new ScheduledThreadPoolExecutor with the given - * initial parameters. - * - * @param corePoolSize the number of threads to keep in the pool, - * even if they are idle - * @param threadFactory the factory to use when the executor - * creates a new thread - * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> - * @throws NullPointerException if threadFactory is null - */ - public ScheduledThreadPoolExecutor(int corePoolSize, - ThreadFactory threadFactory) { - super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, - new DelayedWorkQueue(), threadFactory); - } - - /** - * Creates a new ScheduledThreadPoolExecutor with the given - * initial parameters. - * - * @param corePoolSize the number of threads to keep in the pool, - * even if they are idle - * @param handler the handler to use when execution is blocked - * because the thread bounds and queue capacities are reached - * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> - * @throws NullPointerException if handler is null - */ - public ScheduledThreadPoolExecutor(int corePoolSize, - RejectedExecutionHandler handler) { - super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, - new DelayedWorkQueue(), handler); - } - - /** - * Creates a new ScheduledThreadPoolExecutor with the given - * initial parameters. - * - * @param corePoolSize the number of threads to keep in the pool, - * even if they are idle - * @param threadFactory the factory to use when the executor - * creates a new thread - * @param handler the handler to use when execution is blocked - * because the thread bounds and queue capacities are reached. - * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> - * @throws NullPointerException if threadFactory or handler is null - */ - public ScheduledThreadPoolExecutor(int corePoolSize, - ThreadFactory threadFactory, - RejectedExecutionHandler handler) { - super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, - new DelayedWorkQueue(), threadFactory, handler); - } - - public ScheduledFuture<?> schedule(Runnable command, - long delay, - TimeUnit unit) { - if (command == null || unit == null) - throw new NullPointerException(); - long triggerTime = now() + unit.toNanos(delay); - RunnableScheduledFuture<?> t = decorateTask(command, - new ScheduledFutureTask<Boolean>(command, null, triggerTime)); - delayedExecute(t); - return t; - } - - public <V> ScheduledFuture<V> schedule(Callable<V> callable, - long delay, - TimeUnit unit) { - if (callable == null || unit == null) - throw new NullPointerException(); - if (delay < 0) delay = 0; - long triggerTime = now() + unit.toNanos(delay); - RunnableScheduledFuture<V> t = decorateTask(callable, - new ScheduledFutureTask<V>(callable, triggerTime)); - delayedExecute(t); - return t; - } - - public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, - long initialDelay, - long period, - TimeUnit unit) { - if (command == null || unit == null) - throw new NullPointerException(); - if (period <= 0) - throw new IllegalArgumentException(); - if (initialDelay < 0) initialDelay = 0; - long triggerTime = now() + unit.toNanos(initialDelay); - RunnableScheduledFuture<?> t = decorateTask(command, - new ScheduledFutureTask<Object>(command, - null, - triggerTime, - unit.toNanos(period))); - delayedExecute(t); - return t; - } - - public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, - long initialDelay, - long delay, - TimeUnit unit) { - if (command == null || unit == null) - throw new NullPointerException(); - if (delay <= 0) - throw new IllegalArgumentException(); - if (initialDelay < 0) initialDelay = 0; - long triggerTime = now() + unit.toNanos(initialDelay); - RunnableScheduledFuture<?> t = decorateTask(command, - new ScheduledFutureTask<Boolean>(command, - null, - triggerTime, - unit.toNanos(-delay))); - delayedExecute(t); - return t; - } - - - /** - * Executes command with zero required delay. This has effect - * equivalent to <tt>schedule(command, 0, anyUnit)</tt>. Note - * that inspections of the queue and of the list returned by - * <tt>shutdownNow</tt> will access the zero-delayed - * {@link ScheduledFuture}, not the <tt>command</tt> itself. - * - * @param command the task to execute - * @throws RejectedExecutionException at discretion of - * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted - * for execution because the executor has been shut down. - * @throws NullPointerException if command is null - */ - public void execute(Runnable command) { - if (command == null) - throw new NullPointerException(); - schedule(command, 0, TimeUnit.NANOSECONDS); - } - - // Override AbstractExecutorService methods - - public Future<?> submit(Runnable task) { - return schedule(task, 0, TimeUnit.NANOSECONDS); - } - - public <T> Future<T> submit(Runnable task, T result) { - return schedule(Executors.callable(task, result), - 0, TimeUnit.NANOSECONDS); - } - - public <T> Future<T> submit(Callable<T> task) { - return schedule(task, 0, TimeUnit.NANOSECONDS); - } - - /** - * Sets the policy on whether to continue executing existing periodic - * tasks even when this executor has been <tt>shutdown</tt>. In - * this case, these tasks will only terminate upon - * <tt>shutdownNow</tt>, or after setting the policy to - * <tt>false</tt> when already shutdown. This value is by default - * false. - * - * @param value if true, continue after shutdown, else don't. - * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy - */ - public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) { - continueExistingPeriodicTasksAfterShutdown = value; - if (!value && isShutdown()) - cancelUnwantedTasks(); - } - - /** - * Gets the policy on whether to continue executing existing - * periodic tasks even when this executor has been - * <tt>shutdown</tt>. In this case, these tasks will only - * terminate upon <tt>shutdownNow</tt> or after setting the policy - * to <tt>false</tt> when already shutdown. This value is by - * default false. - * - * @return true if will continue after shutdown - * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy - */ - public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() { - return continueExistingPeriodicTasksAfterShutdown; - } - - /** - * Sets the policy on whether to execute existing delayed - * tasks even when this executor has been <tt>shutdown</tt>. In - * this case, these tasks will only terminate upon - * <tt>shutdownNow</tt>, or after setting the policy to - * <tt>false</tt> when already shutdown. This value is by default - * true. - * - * @param value if true, execute after shutdown, else don't. - * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy - */ - public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) { - executeExistingDelayedTasksAfterShutdown = value; - if (!value && isShutdown()) - cancelUnwantedTasks(); - } - - /** - * Gets the policy on whether to execute existing delayed - * tasks even when this executor has been <tt>shutdown</tt>. In - * this case, these tasks will only terminate upon - * <tt>shutdownNow</tt>, or after setting the policy to - * <tt>false</tt> when already shutdown. This value is by default - * true. - * - * @return true if will execute after shutdown - * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy - */ - public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() { - return executeExistingDelayedTasksAfterShutdown; - } - - - /** - * Initiates an orderly shutdown in which previously submitted - * tasks are executed, but no new tasks will be accepted. If the - * <tt>ExecuteExistingDelayedTasksAfterShutdownPolicy</tt> has - * been set <tt>false</tt>, existing delayed tasks whose delays - * have not yet elapsed are cancelled. And unless the - * <tt>ContinueExistingPeriodicTasksAfterShutdownPolicy</tt> has - * been set <tt>true</tt>, future executions of existing periodic - * tasks will be cancelled. - */ - public void shutdown() { - cancelUnwantedTasks(); - super.shutdown(); - } - - /** - * Attempts to stop all actively executing tasks, halts the - * processing of waiting tasks, and returns a list of the tasks - * that were awaiting execution. - * - * <p>There are no guarantees beyond best-effort attempts to stop - * processing actively executing tasks. This implementation - * cancels tasks via {@link Thread#interrupt}, so any task that - * fails to respond to interrupts may never terminate. - * - * @return list of tasks that never commenced execution. Each - * element of this list is a {@link ScheduledFuture}, - * including those tasks submitted using <tt>execute</tt>, which - * are for scheduling purposes used as the basis of a zero-delay - * <tt>ScheduledFuture</tt>. - * @throws SecurityException {@inheritDoc} - */ - public List<Runnable> shutdownNow() { - return super.shutdownNow(); - } - - /** - * Returns the task queue used by this executor. Each element of - * this queue is a {@link ScheduledFuture}, including those - * tasks submitted using <tt>execute</tt> which are for scheduling - * purposes used as the basis of a zero-delay - * <tt>ScheduledFuture</tt>. Iteration over this queue is - * <em>not</em> guaranteed to traverse tasks in the order in - * which they will execute. - * - * @return the task queue - */ - public BlockingQueue<Runnable> getQueue() { - return super.getQueue(); - } - - /** - * An annoying wrapper class to convince javac to use a - * DelayQueue<RunnableScheduledFuture> as a BlockingQueue<Runnable> - */ - private static class DelayedWorkQueue - extends AbstractCollection<Runnable> - implements BlockingQueue<Runnable> { - - private final DelayQueue<RunnableScheduledFuture> dq = new DelayQueue<RunnableScheduledFuture>(); - public Runnable poll() { return dq.poll(); } - public Runnable peek() { return dq.peek(); } - public Runnable take() throws InterruptedException { return dq.take(); } - public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException { - return dq.poll(timeout, unit); - } - - public boolean add(Runnable x) { - return dq.add((RunnableScheduledFuture)x); - } - public boolean offer(Runnable x) { - return dq.offer((RunnableScheduledFuture)x); - } - public void put(Runnable x) { - dq.put((RunnableScheduledFuture)x); - } - public boolean offer(Runnable x, long timeout, TimeUnit unit) { - return dq.offer((RunnableScheduledFuture)x, timeout, unit); - } - - public Runnable remove() { return dq.remove(); } - public Runnable element() { return dq.element(); } - public void clear() { dq.clear(); } - public int drainTo(Collection<? super Runnable> c) { return dq.drainTo(c); } - public int drainTo(Collection<? super Runnable> c, int maxElements) { - return dq.drainTo(c, maxElements); - } - - public int remainingCapacity() { return dq.remainingCapacity(); } - public boolean remove(Object x) { return dq.remove(x); } - public boolean contains(Object x) { return dq.contains(x); } - public int size() { return dq.size(); } - public boolean isEmpty() { return dq.isEmpty(); } - public Object[] toArray() { return dq.toArray(); } - public <T> T[] toArray(T[] array) { return dq.toArray(array); } - public Iterator<Runnable> iterator() { - return new Iterator<Runnable>() { - private Iterator<RunnableScheduledFuture> it = dq.iterator(); - public boolean hasNext() { return it.hasNext(); } - public Runnable next() { return it.next(); } - public void remove() { it.remove(); } - }; - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Semaphore.java b/libjava/classpath/external/jsr166/java/util/concurrent/Semaphore.java deleted file mode 100644 index 1052364..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/Semaphore.java +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.*; -import java.util.concurrent.locks.*; -import java.util.concurrent.atomic.*; - -/** - * A counting semaphore. Conceptually, a semaphore maintains a set of - * permits. Each {@link #acquire} blocks if necessary until a permit is - * available, and then takes it. Each {@link #release} adds a permit, - * potentially releasing a blocking acquirer. - * However, no actual permit objects are used; the {@code Semaphore} just - * keeps a count of the number available and acts accordingly. - * - * <p>Semaphores are often used to restrict the number of threads than can - * access some (physical or logical) resource. For example, here is - * a class that uses a semaphore to control access to a pool of items: - * <pre> - * class Pool { - * private static final int MAX_AVAILABLE = 100; - * private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); - * - * public Object getItem() throws InterruptedException { - * available.acquire(); - * return getNextAvailableItem(); - * } - * - * public void putItem(Object x) { - * if (markAsUnused(x)) - * available.release(); - * } - * - * // Not a particularly efficient data structure; just for demo - * - * protected Object[] items = ... whatever kinds of items being managed - * protected boolean[] used = new boolean[MAX_AVAILABLE]; - * - * protected synchronized Object getNextAvailableItem() { - * for (int i = 0; i < MAX_AVAILABLE; ++i) { - * if (!used[i]) { - * used[i] = true; - * return items[i]; - * } - * } - * return null; // not reached - * } - * - * protected synchronized boolean markAsUnused(Object item) { - * for (int i = 0; i < MAX_AVAILABLE; ++i) { - * if (item == items[i]) { - * if (used[i]) { - * used[i] = false; - * return true; - * } else - * return false; - * } - * } - * return false; - * } - * - * } - * </pre> - * - * <p>Before obtaining an item each thread must acquire a permit from - * the semaphore, guaranteeing that an item is available for use. When - * the thread has finished with the item it is returned back to the - * pool and a permit is returned to the semaphore, allowing another - * thread to acquire that item. Note that no synchronization lock is - * held when {@link #acquire} is called as that would prevent an item - * from being returned to the pool. The semaphore encapsulates the - * synchronization needed to restrict access to the pool, separately - * from any synchronization needed to maintain the consistency of the - * pool itself. - * - * <p>A semaphore initialized to one, and which is used such that it - * only has at most one permit available, can serve as a mutual - * exclusion lock. This is more commonly known as a <em>binary - * semaphore</em>, because it only has two states: one permit - * available, or zero permits available. When used in this way, the - * binary semaphore has the property (unlike many {@link Lock} - * implementations), that the "lock" can be released by a - * thread other than the owner (as semaphores have no notion of - * ownership). This can be useful in some specialized contexts, such - * as deadlock recovery. - * - * <p> The constructor for this class optionally accepts a - * <em>fairness</em> parameter. When set false, this class makes no - * guarantees about the order in which threads acquire permits. In - * particular, <em>barging</em> is permitted, that is, a thread - * invoking {@link #acquire} can be allocated a permit ahead of a - * thread that has been waiting - logically the new thread places itself at - * the head of the queue of waiting threads. When fairness is set true, the - * semaphore guarantees that threads invoking any of the {@link - * #acquire() acquire} methods are selected to obtain permits in the order in - * which their invocation of those methods was processed - * (first-in-first-out; FIFO). Note that FIFO ordering necessarily - * applies to specific internal points of execution within these - * methods. So, it is possible for one thread to invoke - * {@code acquire} before another, but reach the ordering point after - * the other, and similarly upon return from the method. - * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not - * honor the fairness setting, but will take any permits that are - * available. - * - * <p>Generally, semaphores used to control resource access should be - * initialized as fair, to ensure that no thread is starved out from - * accessing a resource. When using semaphores for other kinds of - * synchronization control, the throughput advantages of non-fair - * ordering often outweigh fairness considerations. - * - * <p>This class also provides convenience methods to {@link - * #acquire(int) acquire} and {@link #release(int) release} multiple - * permits at a time. Beware of the increased risk of indefinite - * postponement when these methods are used without fairness set true. - * - * <p>Memory consistency effects: Actions in a thread prior to calling - * a "release" method such as {@code release()} - * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> - * actions following a successful "acquire" method such as {@code acquire()} - * in another thread. - * - * @since 1.5 - * @author Doug Lea - * - */ - -public class Semaphore implements java.io.Serializable { - private static final long serialVersionUID = -3222578661600680210L; - /** All mechanics via AbstractQueuedSynchronizer subclass */ - private final Sync sync; - - /** - * Synchronization implementation for semaphore. Uses AQS state - * to represent permits. Subclassed into fair and nonfair - * versions. - */ - abstract static class Sync extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = 1192457210091910933L; - - Sync(int permits) { - setState(permits); - } - - final int getPermits() { - return getState(); - } - - final int nonfairTryAcquireShared(int acquires) { - for (;;) { - int available = getState(); - int remaining = available - acquires; - if (remaining < 0 || - compareAndSetState(available, remaining)) - return remaining; - } - } - - protected final boolean tryReleaseShared(int releases) { - for (;;) { - int p = getState(); - if (compareAndSetState(p, p + releases)) - return true; - } - } - - final void reducePermits(int reductions) { - for (;;) { - int current = getState(); - int next = current - reductions; - if (compareAndSetState(current, next)) - return; - } - } - - final int drainPermits() { - for (;;) { - int current = getState(); - if (current == 0 || compareAndSetState(current, 0)) - return current; - } - } - } - - /** - * NonFair version - */ - final static class NonfairSync extends Sync { - private static final long serialVersionUID = -2694183684443567898L; - - NonfairSync(int permits) { - super(permits); - } - - protected int tryAcquireShared(int acquires) { - return nonfairTryAcquireShared(acquires); - } - } - - /** - * Fair version - */ - final static class FairSync extends Sync { - private static final long serialVersionUID = 2014338818796000944L; - - FairSync(int permits) { - super(permits); - } - - protected int tryAcquireShared(int acquires) { - Thread current = Thread.currentThread(); - for (;;) { - Thread first = getFirstQueuedThread(); - if (first != null && first != current) - return -1; - int available = getState(); - int remaining = available - acquires; - if (remaining < 0 || - compareAndSetState(available, remaining)) - return remaining; - } - } - } - - /** - * Creates a {@code Semaphore} with the given number of - * permits and nonfair fairness setting. - * - * @param permits the initial number of permits available. - * This value may be negative, in which case releases - * must occur before any acquires will be granted. - */ - public Semaphore(int permits) { - sync = new NonfairSync(permits); - } - - /** - * Creates a {@code Semaphore} with the given number of - * permits and the given fairness setting. - * - * @param permits the initial number of permits available. - * This value may be negative, in which case releases - * must occur before any acquires will be granted. - * @param fair {@code true} if this semaphore will guarantee - * first-in first-out granting of permits under contention, - * else {@code false} - */ - public Semaphore(int permits, boolean fair) { - sync = (fair)? new FairSync(permits) : new NonfairSync(permits); - } - - /** - * Acquires a permit from this semaphore, blocking until one is - * available, or the thread is {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires a permit, if one is available and returns immediately, - * reducing the number of available permits by one. - * - * <p>If no permit is available then the current thread becomes - * disabled for thread scheduling purposes and lies dormant until - * one of two things happens: - * <ul> - * <li>Some other thread invokes the {@link #release} method for this - * semaphore and the current thread is next to be assigned a permit; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread. - * </ul> - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * for a permit, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * @throws InterruptedException if the current thread is interrupted - */ - public void acquire() throws InterruptedException { - sync.acquireSharedInterruptibly(1); - } - - /** - * Acquires a permit from this semaphore, blocking until one is - * available. - * - * <p>Acquires a permit, if one is available and returns immediately, - * reducing the number of available permits by one. - * - * <p>If no permit is available then the current thread becomes - * disabled for thread scheduling purposes and lies dormant until - * some other thread invokes the {@link #release} method for this - * semaphore and the current thread is next to be assigned a permit. - * - * <p>If the current thread is {@linkplain Thread#interrupt interrupted} - * while waiting for a permit then it will continue to wait, but the - * time at which the thread is assigned a permit may change compared to - * the time it would have received the permit had no interruption - * occurred. When the thread does return from this method its interrupt - * status will be set. - */ - public void acquireUninterruptibly() { - sync.acquireShared(1); - } - - /** - * Acquires a permit from this semaphore, only if one is available at the - * time of invocation. - * - * <p>Acquires a permit, if one is available and returns immediately, - * with the value {@code true}, - * reducing the number of available permits by one. - * - * <p>If no permit is available then this method will return - * immediately with the value {@code false}. - * - * <p>Even when this semaphore has been set to use a - * fair ordering policy, a call to {@code tryAcquire()} <em>will</em> - * immediately acquire a permit if one is available, whether or not - * other threads are currently waiting. - * This "barging" behavior can be useful in certain - * circumstances, even though it breaks fairness. If you want to honor - * the fairness setting, then use - * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) } - * which is almost equivalent (it also detects interruption). - * - * @return {@code true} if a permit was acquired and {@code false} - * otherwise - */ - public boolean tryAcquire() { - return sync.nonfairTryAcquireShared(1) >= 0; - } - - /** - * Acquires a permit from this semaphore, if one becomes available - * within the given waiting time and the current thread has not - * been {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires a permit, if one is available and returns immediately, - * with the value {@code true}, - * reducing the number of available permits by one. - * - * <p>If no permit is available then the current thread becomes - * disabled for thread scheduling purposes and lies dormant until - * one of three things happens: - * <ul> - * <li>Some other thread invokes the {@link #release} method for this - * semaphore and the current thread is next to be assigned a permit; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * <li>The specified waiting time elapses. - * </ul> - * - * <p>If a permit is acquired then the value {@code true} is returned. - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * to acquire a permit, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p>If the specified waiting time elapses then the value {@code false} - * is returned. If the time is less than or equal to zero, the method - * will not wait at all. - * - * @param timeout the maximum time to wait for a permit - * @param unit the time unit of the {@code timeout} argument - * @return {@code true} if a permit was acquired and {@code false} - * if the waiting time elapsed before a permit was acquired - * @throws InterruptedException if the current thread is interrupted - */ - public boolean tryAcquire(long timeout, TimeUnit unit) - throws InterruptedException { - return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); - } - - /** - * Releases a permit, returning it to the semaphore. - * - * <p>Releases a permit, increasing the number of available permits by - * one. If any threads are trying to acquire a permit, then one is - * selected and given the permit that was just released. That thread - * is (re)enabled for thread scheduling purposes. - * - * <p>There is no requirement that a thread that releases a permit must - * have acquired that permit by calling {@link #acquire}. - * Correct usage of a semaphore is established by programming convention - * in the application. - */ - public void release() { - sync.releaseShared(1); - } - - /** - * Acquires the given number of permits from this semaphore, - * blocking until all are available, - * or the thread is {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires the given number of permits, if they are available, - * and returns immediately, reducing the number of available permits - * by the given amount. - * - * <p>If insufficient permits are available then the current thread becomes - * disabled for thread scheduling purposes and lies dormant until - * one of two things happens: - * <ul> - * <li>Some other thread invokes one of the {@link #release() release} - * methods for this semaphore, the current thread is next to be assigned - * permits and the number of available permits satisfies this request; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread. - * </ul> - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * for a permit, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * Any permits that were to be assigned to this thread are instead - * assigned to other threads trying to acquire permits, as if - * permits had been made available by a call to {@link #release()}. - * - * @param permits the number of permits to acquire - * @throws InterruptedException if the current thread is interrupted - * @throws IllegalArgumentException if {@code permits} is negative - */ - public void acquire(int permits) throws InterruptedException { - if (permits < 0) throw new IllegalArgumentException(); - sync.acquireSharedInterruptibly(permits); - } - - /** - * Acquires the given number of permits from this semaphore, - * blocking until all are available. - * - * <p>Acquires the given number of permits, if they are available, - * and returns immediately, reducing the number of available permits - * by the given amount. - * - * <p>If insufficient permits are available then the current thread becomes - * disabled for thread scheduling purposes and lies dormant until - * some other thread invokes one of the {@link #release() release} - * methods for this semaphore, the current thread is next to be assigned - * permits and the number of available permits satisfies this request. - * - * <p>If the current thread is {@linkplain Thread#interrupt interrupted} - * while waiting for permits then it will continue to wait and its - * position in the queue is not affected. When the thread does return - * from this method its interrupt status will be set. - * - * @param permits the number of permits to acquire - * @throws IllegalArgumentException if {@code permits} is negative - * - */ - public void acquireUninterruptibly(int permits) { - if (permits < 0) throw new IllegalArgumentException(); - sync.acquireShared(permits); - } - - /** - * Acquires the given number of permits from this semaphore, only - * if all are available at the time of invocation. - * - * <p>Acquires the given number of permits, if they are available, and - * returns immediately, with the value {@code true}, - * reducing the number of available permits by the given amount. - * - * <p>If insufficient permits are available then this method will return - * immediately with the value {@code false} and the number of available - * permits is unchanged. - * - * <p>Even when this semaphore has been set to use a fair ordering - * policy, a call to {@code tryAcquire} <em>will</em> - * immediately acquire a permit if one is available, whether or - * not other threads are currently waiting. This - * "barging" behavior can be useful in certain - * circumstances, even though it breaks fairness. If you want to - * honor the fairness setting, then use {@link #tryAcquire(int, - * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) } - * which is almost equivalent (it also detects interruption). - * - * @param permits the number of permits to acquire - * @return {@code true} if the permits were acquired and - * {@code false} otherwise - * @throws IllegalArgumentException if {@code permits} is negative - */ - public boolean tryAcquire(int permits) { - if (permits < 0) throw new IllegalArgumentException(); - return sync.nonfairTryAcquireShared(permits) >= 0; - } - - /** - * Acquires the given number of permits from this semaphore, if all - * become available within the given waiting time and the current - * thread has not been {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires the given number of permits, if they are available and - * returns immediately, with the value {@code true}, - * reducing the number of available permits by the given amount. - * - * <p>If insufficient permits are available then - * the current thread becomes disabled for thread scheduling - * purposes and lies dormant until one of three things happens: - * <ul> - * <li>Some other thread invokes one of the {@link #release() release} - * methods for this semaphore, the current thread is next to be assigned - * permits and the number of available permits satisfies this request; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * <li>The specified waiting time elapses. - * </ul> - * - * <p>If the permits are acquired then the value {@code true} is returned. - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * to acquire the permits, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * Any permits that were to be assigned to this thread, are instead - * assigned to other threads trying to acquire permits, as if - * the permits had been made available by a call to {@link #release()}. - * - * <p>If the specified waiting time elapses then the value {@code false} - * is returned. If the time is less than or equal to zero, the method - * will not wait at all. Any permits that were to be assigned to this - * thread, are instead assigned to other threads trying to acquire - * permits, as if the permits had been made available by a call to - * {@link #release()}. - * - * @param permits the number of permits to acquire - * @param timeout the maximum time to wait for the permits - * @param unit the time unit of the {@code timeout} argument - * @return {@code true} if all permits were acquired and {@code false} - * if the waiting time elapsed before all permits were acquired - * @throws InterruptedException if the current thread is interrupted - * @throws IllegalArgumentException if {@code permits} is negative - */ - public boolean tryAcquire(int permits, long timeout, TimeUnit unit) - throws InterruptedException { - if (permits < 0) throw new IllegalArgumentException(); - return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout)); - } - - /** - * Releases the given number of permits, returning them to the semaphore. - * - * <p>Releases the given number of permits, increasing the number of - * available permits by that amount. - * If any threads are trying to acquire permits, then one - * is selected and given the permits that were just released. - * If the number of available permits satisfies that thread's request - * then that thread is (re)enabled for thread scheduling purposes; - * otherwise the thread will wait until sufficient permits are available. - * If there are still permits available - * after this thread's request has been satisfied, then those permits - * are assigned in turn to other threads trying to acquire permits. - * - * <p>There is no requirement that a thread that releases a permit must - * have acquired that permit by calling {@link Semaphore#acquire acquire}. - * Correct usage of a semaphore is established by programming convention - * in the application. - * - * @param permits the number of permits to release - * @throws IllegalArgumentException if {@code permits} is negative - */ - public void release(int permits) { - if (permits < 0) throw new IllegalArgumentException(); - sync.releaseShared(permits); - } - - /** - * Returns the current number of permits available in this semaphore. - * - * <p>This method is typically used for debugging and testing purposes. - * - * @return the number of permits available in this semaphore - */ - public int availablePermits() { - return sync.getPermits(); - } - - /** - * Acquires and returns all permits that are immediately available. - * - * @return the number of permits acquired - */ - public int drainPermits() { - return sync.drainPermits(); - } - - /** - * Shrinks the number of available permits by the indicated - * reduction. This method can be useful in subclasses that use - * semaphores to track resources that become unavailable. This - * method differs from {@code acquire} in that it does not block - * waiting for permits to become available. - * - * @param reduction the number of permits to remove - * @throws IllegalArgumentException if {@code reduction} is negative - */ - protected void reducePermits(int reduction) { - if (reduction < 0) throw new IllegalArgumentException(); - sync.reducePermits(reduction); - } - - /** - * Returns {@code true} if this semaphore has fairness set true. - * - * @return {@code true} if this semaphore has fairness set true - */ - public boolean isFair() { - return sync instanceof FairSync; - } - - /** - * Queries whether any threads are waiting to acquire. Note that - * because cancellations may occur at any time, a {@code true} - * return does not guarantee that any other thread will ever - * acquire. This method is designed primarily for use in - * monitoring of the system state. - * - * @return {@code true} if there may be other threads waiting to - * acquire the lock - */ - public final boolean hasQueuedThreads() { - return sync.hasQueuedThreads(); - } - - /** - * Returns an estimate of the number of threads waiting to acquire. - * The value is only an estimate because the number of threads may - * change dynamically while this method traverses internal data - * structures. This method is designed for use in monitoring of the - * system state, not for synchronization control. - * - * @return the estimated number of threads waiting for this lock - */ - public final int getQueueLength() { - return sync.getQueueLength(); - } - - /** - * Returns a collection containing threads that may be waiting to acquire. - * Because the actual set of threads may change dynamically while - * constructing this result, the returned collection is only a best-effort - * estimate. The elements of the returned collection are in no particular - * order. This method is designed to facilitate construction of - * subclasses that provide more extensive monitoring facilities. - * - * @return the collection of threads - */ - protected Collection<Thread> getQueuedThreads() { - return sync.getQueuedThreads(); - } - - /** - * Returns a string identifying this semaphore, as well as its state. - * The state, in brackets, includes the String {@code "Permits ="} - * followed by the number of permits. - * - * @return a string identifying this semaphore, as well as its state - */ - public String toString() { - return super.toString() + "[Permits = " + sync.getPermits() + "]"; - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/SynchronousQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/SynchronousQueue.java deleted file mode 100644 index 92f586c..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/SynchronousQueue.java +++ /dev/null @@ -1,1127 +0,0 @@ -/* - * Written by Doug Lea, Bill Scherer, and Michael Scott with - * assistance from members of JCP JSR-166 Expert Group and released to - * the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.locks.*; -import java.util.concurrent.atomic.*; -import java.util.*; - -/** - * A {@linkplain BlockingQueue blocking queue} in which each insert - * operation must wait for a corresponding remove operation by another - * thread, and vice versa. A synchronous queue does not have any - * internal capacity, not even a capacity of one. You cannot - * <tt>peek</tt> at a synchronous queue because an element is only - * present when you try to remove it; you cannot insert an element - * (using any method) unless another thread is trying to remove it; - * you cannot iterate as there is nothing to iterate. The - * <em>head</em> of the queue is the element that the first queued - * inserting thread is trying to add to the queue; if there is no such - * queued thread then no element is available for removal and - * <tt>poll()</tt> will return <tt>null</tt>. For purposes of other - * <tt>Collection</tt> methods (for example <tt>contains</tt>), a - * <tt>SynchronousQueue</tt> acts as an empty collection. This queue - * does not permit <tt>null</tt> elements. - * - * <p>Synchronous queues are similar to rendezvous channels used in - * CSP and Ada. They are well suited for handoff designs, in which an - * object running in one thread must sync up with an object running - * in another thread in order to hand it some information, event, or - * task. - * - * <p> This class supports an optional fairness policy for ordering - * waiting producer and consumer threads. By default, this ordering - * is not guaranteed. However, a queue constructed with fairness set - * to <tt>true</tt> grants threads access in FIFO order. - * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. - * - * <p>This class is a member of the - * <a href="{@docRoot}/../technotes/guides/collections/index.html"> - * Java Collections Framework</a>. - * - * @since 1.5 - * @author Doug Lea and Bill Scherer and Michael Scott - * @param <E> the type of elements held in this collection - */ -public class SynchronousQueue<E> extends AbstractQueue<E> - implements BlockingQueue<E>, java.io.Serializable { - private static final long serialVersionUID = -3223113410248163686L; - - /* - * This class implements extensions of the dual stack and dual - * queue algorithms described in "Nonblocking Concurrent Objects - * with Condition Synchronization", by W. N. Scherer III and - * M. L. Scott. 18th Annual Conf. on Distributed Computing, - * Oct. 2004 (see also - * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/duals.html). - * The (Lifo) stack is used for non-fair mode, and the (Fifo) - * queue for fair mode. The performance of the two is generally - * similar. Fifo usually supports higher throughput under - * contention but Lifo maintains higher thread locality in common - * applications. - * - * A dual queue (and similarly stack) is one that at any given - * time either holds "data" -- items provided by put operations, - * or "requests" -- slots representing take operations, or is - * empty. A call to "fulfill" (i.e., a call requesting an item - * from a queue holding data or vice versa) dequeues a - * complementary node. The most interesting feature of these - * queues is that any operation can figure out which mode the - * queue is in, and act accordingly without needing locks. - * - * Both the queue and stack extend abstract class Transferer - * defining the single method transfer that does a put or a - * take. These are unified into a single method because in dual - * data structures, the put and take operations are symmetrical, - * so nearly all code can be combined. The resulting transfer - * methods are on the long side, but are easier to follow than - * they would be if broken up into nearly-duplicated parts. - * - * The queue and stack data structures share many conceptual - * similarities but very few concrete details. For simplicity, - * they are kept distinct so that they can later evolve - * separately. - * - * The algorithms here differ from the versions in the above paper - * in extending them for use in synchronous queues, as well as - * dealing with cancellation. The main differences include: - * - * 1. The original algorithms used bit-marked pointers, but - * the ones here use mode bits in nodes, leading to a number - * of further adaptations. - * 2. SynchronousQueues must block threads waiting to become - * fulfilled. - * 3. Support for cancellation via timeout and interrupts, - * including cleaning out cancelled nodes/threads - * from lists to avoid garbage retention and memory depletion. - * - * Blocking is mainly accomplished using LockSupport park/unpark, - * except that nodes that appear to be the next ones to become - * fulfilled first spin a bit (on multiprocessors only). On very - * busy synchronous queues, spinning can dramatically improve - * throughput. And on less busy ones, the amount of spinning is - * small enough not to be noticeable. - * - * Cleaning is done in different ways in queues vs stacks. For - * queues, we can almost always remove a node immediately in O(1) - * time (modulo retries for consistency checks) when it is - * cancelled. But if it may be pinned as the current tail, it must - * wait until some subsequent cancellation. For stacks, we need a - * potentially O(n) traversal to be sure that we can remove the - * node, but this can run concurrently with other threads - * accessing the stack. - * - * While garbage collection takes care of most node reclamation - * issues that otherwise complicate nonblocking algorithms, care - * is taken to "forget" references to data, other nodes, and - * threads that might be held on to long-term by blocked - * threads. In cases where setting to null would otherwise - * conflict with main algorithms, this is done by changing a - * node's link to now point to the node itself. This doesn't arise - * much for Stack nodes (because blocked threads do not hang on to - * old head pointers), but references in Queue nodes must be - * aggressively forgotten to avoid reachability of everything any - * node has ever referred to since arrival. - */ - - /** - * Shared internal API for dual stacks and queues. - */ - static abstract class Transferer { - /** - * Performs a put or take. - * - * @param e if non-null, the item to be handed to a consumer; - * if null, requests that transfer return an item - * offered by producer. - * @param timed if this operation should timeout - * @param nanos the timeout, in nanoseconds - * @return if non-null, the item provided or received; if null, - * the operation failed due to timeout or interrupt -- - * the caller can distinguish which of these occurred - * by checking Thread.interrupted. - */ - abstract Object transfer(Object e, boolean timed, long nanos); - } - - /** The number of CPUs, for spin control */ - static final int NCPUS = Runtime.getRuntime().availableProcessors(); - - /** - * The number of times to spin before blocking in timed waits. - * The value is empirically derived -- it works well across a - * variety of processors and OSes. Empirically, the best value - * seems not to vary with number of CPUs (beyond 2) so is just - * a constant. - */ - static final int maxTimedSpins = (NCPUS < 2)? 0 : 32; - - /** - * The number of times to spin before blocking in untimed waits. - * This is greater than timed value because untimed waits spin - * faster since they don't need to check times on each spin. - */ - static final int maxUntimedSpins = maxTimedSpins * 16; - - /** - * The number of nanoseconds for which it is faster to spin - * rather than to use timed park. A rough estimate suffices. - */ - static final long spinForTimeoutThreshold = 1000L; - - /** Dual stack */ - static final class TransferStack extends Transferer { - /* - * This extends Scherer-Scott dual stack algorithm, differing, - * among other ways, by using "covering" nodes rather than - * bit-marked pointers: Fulfilling operations push on marker - * nodes (with FULFILLING bit set in mode) to reserve a spot - * to match a waiting node. - */ - - /* Modes for SNodes, ORed together in node fields */ - /** Node represents an unfulfilled consumer */ - static final int REQUEST = 0; - /** Node represents an unfulfilled producer */ - static final int DATA = 1; - /** Node is fulfilling another unfulfilled DATA or REQUEST */ - static final int FULFILLING = 2; - - /** Return true if m has fulfilling bit set */ - static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; } - - /** Node class for TransferStacks. */ - static final class SNode { - volatile SNode next; // next node in stack - volatile SNode match; // the node matched to this - volatile Thread waiter; // to control park/unpark - Object item; // data; or null for REQUESTs - int mode; - // Note: item and mode fields don't need to be volatile - // since they are always written before, and read after, - // other volatile/atomic operations. - - SNode(Object item) { - this.item = item; - } - - static final AtomicReferenceFieldUpdater<SNode, SNode> - nextUpdater = AtomicReferenceFieldUpdater.newUpdater - (SNode.class, SNode.class, "next"); - - boolean casNext(SNode cmp, SNode val) { - return (cmp == next && - nextUpdater.compareAndSet(this, cmp, val)); - } - - static final AtomicReferenceFieldUpdater<SNode, SNode> - matchUpdater = AtomicReferenceFieldUpdater.newUpdater - (SNode.class, SNode.class, "match"); - - /** - * Tries to match node s to this node, if so, waking up thread. - * Fulfillers call tryMatch to identify their waiters. - * Waiters block until they have been matched. - * - * @param s the node to match - * @return true if successfully matched to s - */ - boolean tryMatch(SNode s) { - if (match == null && - matchUpdater.compareAndSet(this, null, s)) { - Thread w = waiter; - if (w != null) { // waiters need at most one unpark - waiter = null; - LockSupport.unpark(w); - } - return true; - } - return match == s; - } - - /** - * Tries to cancel a wait by matching node to itself. - */ - void tryCancel() { - matchUpdater.compareAndSet(this, null, this); - } - - boolean isCancelled() { - return match == this; - } - } - - /** The head (top) of the stack */ - volatile SNode head; - - static final AtomicReferenceFieldUpdater<TransferStack, SNode> - headUpdater = AtomicReferenceFieldUpdater.newUpdater - (TransferStack.class, SNode.class, "head"); - - boolean casHead(SNode h, SNode nh) { - return h == head && headUpdater.compareAndSet(this, h, nh); - } - - /** - * Creates or resets fields of a node. Called only from transfer - * where the node to push on stack is lazily created and - * reused when possible to help reduce intervals between reads - * and CASes of head and to avoid surges of garbage when CASes - * to push nodes fail due to contention. - */ - static SNode snode(SNode s, Object e, SNode next, int mode) { - if (s == null) s = new SNode(e); - s.mode = mode; - s.next = next; - return s; - } - - /** - * Puts or takes an item. - */ - Object transfer(Object e, boolean timed, long nanos) { - /* - * Basic algorithm is to loop trying one of three actions: - * - * 1. If apparently empty or already containing nodes of same - * mode, try to push node on stack and wait for a match, - * returning it, or null if cancelled. - * - * 2. If apparently containing node of complementary mode, - * try to push a fulfilling node on to stack, match - * with corresponding waiting node, pop both from - * stack, and return matched item. The matching or - * unlinking might not actually be necessary because of - * other threads performing action 3: - * - * 3. If top of stack already holds another fulfilling node, - * help it out by doing its match and/or pop - * operations, and then continue. The code for helping - * is essentially the same as for fulfilling, except - * that it doesn't return the item. - */ - - SNode s = null; // constructed/reused as needed - int mode = (e == null)? REQUEST : DATA; - - for (;;) { - SNode h = head; - if (h == null || h.mode == mode) { // empty or same-mode - if (timed && nanos <= 0) { // can't wait - if (h != null && h.isCancelled()) - casHead(h, h.next); // pop cancelled node - else - return null; - } else if (casHead(h, s = snode(s, e, h, mode))) { - SNode m = awaitFulfill(s, timed, nanos); - if (m == s) { // wait was cancelled - clean(s); - return null; - } - if ((h = head) != null && h.next == s) - casHead(h, s.next); // help s's fulfiller - return mode == REQUEST? m.item : s.item; - } - } else if (!isFulfilling(h.mode)) { // try to fulfill - if (h.isCancelled()) // already cancelled - casHead(h, h.next); // pop and retry - else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) { - for (;;) { // loop until matched or waiters disappear - SNode m = s.next; // m is s's match - if (m == null) { // all waiters are gone - casHead(s, null); // pop fulfill node - s = null; // use new node next time - break; // restart main loop - } - SNode mn = m.next; - if (m.tryMatch(s)) { - casHead(s, mn); // pop both s and m - return (mode == REQUEST)? m.item : s.item; - } else // lost match - s.casNext(m, mn); // help unlink - } - } - } else { // help a fulfiller - SNode m = h.next; // m is h's match - if (m == null) // waiter is gone - casHead(h, null); // pop fulfilling node - else { - SNode mn = m.next; - if (m.tryMatch(h)) // help match - casHead(h, mn); // pop both h and m - else // lost match - h.casNext(m, mn); // help unlink - } - } - } - } - - /** - * Spins/blocks until node s is matched by a fulfill operation. - * - * @param s the waiting node - * @param timed true if timed wait - * @param nanos timeout value - * @return matched node, or s if cancelled - */ - SNode awaitFulfill(SNode s, boolean timed, long nanos) { - /* - * When a node/thread is about to block, it sets its waiter - * field and then rechecks state at least one more time - * before actually parking, thus covering race vs - * fulfiller noticing that waiter is non-null so should be - * woken. - * - * When invoked by nodes that appear at the point of call - * to be at the head of the stack, calls to park are - * preceded by spins to avoid blocking when producers and - * consumers are arriving very close in time. This can - * happen enough to bother only on multiprocessors. - * - * The order of checks for returning out of main loop - * reflects fact that interrupts have precedence over - * normal returns, which have precedence over - * timeouts. (So, on timeout, one last check for match is - * done before giving up.) Except that calls from untimed - * SynchronousQueue.{poll/offer} don't check interrupts - * and don't wait at all, so are trapped in transfer - * method rather than calling awaitFulfill. - */ - long lastTime = (timed)? System.nanoTime() : 0; - Thread w = Thread.currentThread(); - SNode h = head; - int spins = (shouldSpin(s)? - (timed? maxTimedSpins : maxUntimedSpins) : 0); - for (;;) { - if (w.isInterrupted()) - s.tryCancel(); - SNode m = s.match; - if (m != null) - return m; - if (timed) { - long now = System.nanoTime(); - nanos -= now - lastTime; - lastTime = now; - if (nanos <= 0) { - s.tryCancel(); - continue; - } - } - if (spins > 0) - spins = shouldSpin(s)? (spins-1) : 0; - else if (s.waiter == null) - s.waiter = w; // establish waiter so can park next iter - else if (!timed) - LockSupport.park(this); - else if (nanos > spinForTimeoutThreshold) - LockSupport.parkNanos(this, nanos); - } - } - - /** - * Returns true if node s is at head or there is an active - * fulfiller. - */ - boolean shouldSpin(SNode s) { - SNode h = head; - return (h == s || h == null || isFulfilling(h.mode)); - } - - /** - * Unlinks s from the stack. - */ - void clean(SNode s) { - s.item = null; // forget item - s.waiter = null; // forget thread - - /* - * At worst we may need to traverse entire stack to unlink - * s. If there are multiple concurrent calls to clean, we - * might not see s if another thread has already removed - * it. But we can stop when we see any node known to - * follow s. We use s.next unless it too is cancelled, in - * which case we try the node one past. We don't check any - * further because we don't want to doubly traverse just to - * find sentinel. - */ - - SNode past = s.next; - if (past != null && past.isCancelled()) - past = past.next; - - // Absorb cancelled nodes at head - SNode p; - while ((p = head) != null && p != past && p.isCancelled()) - casHead(p, p.next); - - // Unsplice embedded nodes - while (p != null && p != past) { - SNode n = p.next; - if (n != null && n.isCancelled()) - p.casNext(n, n.next); - else - p = n; - } - } - } - - /** Dual Queue */ - static final class TransferQueue extends Transferer { - /* - * This extends Scherer-Scott dual queue algorithm, differing, - * among other ways, by using modes within nodes rather than - * marked pointers. The algorithm is a little simpler than - * that for stacks because fulfillers do not need explicit - * nodes, and matching is done by CAS'ing QNode.item field - * from non-null to null (for put) or vice versa (for take). - */ - - /** Node class for TransferQueue. */ - static final class QNode { - volatile QNode next; // next node in queue - volatile Object item; // CAS'ed to or from null - volatile Thread waiter; // to control park/unpark - final boolean isData; - - QNode(Object item, boolean isData) { - this.item = item; - this.isData = isData; - } - - static final AtomicReferenceFieldUpdater<QNode, QNode> - nextUpdater = AtomicReferenceFieldUpdater.newUpdater - (QNode.class, QNode.class, "next"); - - boolean casNext(QNode cmp, QNode val) { - return (next == cmp && - nextUpdater.compareAndSet(this, cmp, val)); - } - - static final AtomicReferenceFieldUpdater<QNode, Object> - itemUpdater = AtomicReferenceFieldUpdater.newUpdater - (QNode.class, Object.class, "item"); - - boolean casItem(Object cmp, Object val) { - return (item == cmp && - itemUpdater.compareAndSet(this, cmp, val)); - } - - /** - * Tries to cancel by CAS'ing ref to this as item. - */ - void tryCancel(Object cmp) { - itemUpdater.compareAndSet(this, cmp, this); - } - - boolean isCancelled() { - return item == this; - } - - /** - * Returns true if this node is known to be off the queue - * because its next pointer has been forgotten due to - * an advanceHead operation. - */ - boolean isOffList() { - return next == this; - } - } - - /** Head of queue */ - transient volatile QNode head; - /** Tail of queue */ - transient volatile QNode tail; - /** - * Reference to a cancelled node that might not yet have been - * unlinked from queue because it was the last inserted node - * when it cancelled. - */ - transient volatile QNode cleanMe; - - TransferQueue() { - QNode h = new QNode(null, false); // initialize to dummy node. - head = h; - tail = h; - } - - static final AtomicReferenceFieldUpdater<TransferQueue, QNode> - headUpdater = AtomicReferenceFieldUpdater.newUpdater - (TransferQueue.class, QNode.class, "head"); - - /** - * Tries to cas nh as new head; if successful, unlink - * old head's next node to avoid garbage retention. - */ - void advanceHead(QNode h, QNode nh) { - if (h == head && headUpdater.compareAndSet(this, h, nh)) - h.next = h; // forget old next - } - - static final AtomicReferenceFieldUpdater<TransferQueue, QNode> - tailUpdater = AtomicReferenceFieldUpdater.newUpdater - (TransferQueue.class, QNode.class, "tail"); - - /** - * Tries to cas nt as new tail. - */ - void advanceTail(QNode t, QNode nt) { - if (tail == t) - tailUpdater.compareAndSet(this, t, nt); - } - - static final AtomicReferenceFieldUpdater<TransferQueue, QNode> - cleanMeUpdater = AtomicReferenceFieldUpdater.newUpdater - (TransferQueue.class, QNode.class, "cleanMe"); - - /** - * Tries to CAS cleanMe slot. - */ - boolean casCleanMe(QNode cmp, QNode val) { - return (cleanMe == cmp && - cleanMeUpdater.compareAndSet(this, cmp, val)); - } - - /** - * Puts or takes an item. - */ - Object transfer(Object e, boolean timed, long nanos) { - /* Basic algorithm is to loop trying to take either of - * two actions: - * - * 1. If queue apparently empty or holding same-mode nodes, - * try to add node to queue of waiters, wait to be - * fulfilled (or cancelled) and return matching item. - * - * 2. If queue apparently contains waiting items, and this - * call is of complementary mode, try to fulfill by CAS'ing - * item field of waiting node and dequeuing it, and then - * returning matching item. - * - * In each case, along the way, check for and try to help - * advance head and tail on behalf of other stalled/slow - * threads. - * - * The loop starts off with a null check guarding against - * seeing uninitialized head or tail values. This never - * happens in current SynchronousQueue, but could if - * callers held non-volatile/final ref to the - * transferer. The check is here anyway because it places - * null checks at top of loop, which is usually faster - * than having them implicitly interspersed. - */ - - QNode s = null; // constructed/reused as needed - boolean isData = (e != null); - - for (;;) { - QNode t = tail; - QNode h = head; - if (t == null || h == null) // saw uninitialized value - continue; // spin - - if (h == t || t.isData == isData) { // empty or same-mode - QNode tn = t.next; - if (t != tail) // inconsistent read - continue; - if (tn != null) { // lagging tail - advanceTail(t, tn); - continue; - } - if (timed && nanos <= 0) // can't wait - return null; - if (s == null) - s = new QNode(e, isData); - if (!t.casNext(null, s)) // failed to link in - continue; - - advanceTail(t, s); // swing tail and wait - Object x = awaitFulfill(s, e, timed, nanos); - if (x == s) { // wait was cancelled - clean(t, s); - return null; - } - - if (!s.isOffList()) { // not already unlinked - advanceHead(t, s); // unlink if head - if (x != null) // and forget fields - s.item = s; - s.waiter = null; - } - return (x != null)? x : e; - - } else { // complementary-mode - QNode m = h.next; // node to fulfill - if (t != tail || m == null || h != head) - continue; // inconsistent read - - Object x = m.item; - if (isData == (x != null) || // m already fulfilled - x == m || // m cancelled - !m.casItem(x, e)) { // lost CAS - advanceHead(h, m); // dequeue and retry - continue; - } - - advanceHead(h, m); // successfully fulfilled - LockSupport.unpark(m.waiter); - return (x != null)? x : e; - } - } - } - - /** - * Spins/blocks until node s is fulfilled. - * - * @param s the waiting node - * @param e the comparison value for checking match - * @param timed true if timed wait - * @param nanos timeout value - * @return matched item, or s if cancelled - */ - Object awaitFulfill(QNode s, Object e, boolean timed, long nanos) { - /* Same idea as TransferStack.awaitFulfill */ - long lastTime = (timed)? System.nanoTime() : 0; - Thread w = Thread.currentThread(); - int spins = ((head.next == s) ? - (timed? maxTimedSpins : maxUntimedSpins) : 0); - for (;;) { - if (w.isInterrupted()) - s.tryCancel(e); - Object x = s.item; - if (x != e) - return x; - if (timed) { - long now = System.nanoTime(); - nanos -= now - lastTime; - lastTime = now; - if (nanos <= 0) { - s.tryCancel(e); - continue; - } - } - if (spins > 0) - --spins; - else if (s.waiter == null) - s.waiter = w; - else if (!timed) - LockSupport.park(this); - else if (nanos > spinForTimeoutThreshold) - LockSupport.parkNanos(this, nanos); - } - } - - /** - * Gets rid of cancelled node s with original predecessor pred. - */ - void clean(QNode pred, QNode s) { - s.waiter = null; // forget thread - /* - * At any given time, exactly one node on list cannot be - * deleted -- the last inserted node. To accommodate this, - * if we cannot delete s, we save its predecessor as - * "cleanMe", deleting the previously saved version - * first. At least one of node s or the node previously - * saved can always be deleted, so this always terminates. - */ - while (pred.next == s) { // Return early if already unlinked - QNode h = head; - QNode hn = h.next; // Absorb cancelled first node as head - if (hn != null && hn.isCancelled()) { - advanceHead(h, hn); - continue; - } - QNode t = tail; // Ensure consistent read for tail - if (t == h) - return; - QNode tn = t.next; - if (t != tail) - continue; - if (tn != null) { - advanceTail(t, tn); - continue; - } - if (s != t) { // If not tail, try to unsplice - QNode sn = s.next; - if (sn == s || pred.casNext(s, sn)) - return; - } - QNode dp = cleanMe; - if (dp != null) { // Try unlinking previous cancelled node - QNode d = dp.next; - QNode dn; - if (d == null || // d is gone or - d == dp || // d is off list or - !d.isCancelled() || // d not cancelled or - (d != t && // d not tail and - (dn = d.next) != null && // has successor - dn != d && // that is on list - dp.casNext(d, dn))) // d unspliced - casCleanMe(dp, null); - if (dp == pred) - return; // s is already saved node - } else if (casCleanMe(null, pred)) - return; // Postpone cleaning s - } - } - } - - /** - * The transferer. Set only in constructor, but cannot be declared - * as final without further complicating serialization. Since - * this is accessed only at most once per public method, there - * isn't a noticeable performance penalty for using volatile - * instead of final here. - */ - private transient volatile Transferer transferer; - - /** - * Creates a <tt>SynchronousQueue</tt> with nonfair access policy. - */ - public SynchronousQueue() { - this(false); - } - - /** - * Creates a <tt>SynchronousQueue</tt> with the specified fairness policy. - * - * @param fair if true, waiting threads contend in FIFO order for - * access; otherwise the order is unspecified. - */ - public SynchronousQueue(boolean fair) { - transferer = (fair)? new TransferQueue() : new TransferStack(); - } - - /** - * Adds the specified element to this queue, waiting if necessary for - * another thread to receive it. - * - * @throws InterruptedException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public void put(E o) throws InterruptedException { - if (o == null) throw new NullPointerException(); - if (transferer.transfer(o, false, 0) == null) { - Thread.interrupted(); - throw new InterruptedException(); - } - } - - /** - * Inserts the specified element into this queue, waiting if necessary - * up to the specified wait time for another thread to receive it. - * - * @return <tt>true</tt> if successful, or <tt>false</tt> if the - * specified waiting time elapses before a consumer appears. - * @throws InterruptedException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - */ - public boolean offer(E o, long timeout, TimeUnit unit) - throws InterruptedException { - if (o == null) throw new NullPointerException(); - if (transferer.transfer(o, true, unit.toNanos(timeout)) != null) - return true; - if (!Thread.interrupted()) - return false; - throw new InterruptedException(); - } - - /** - * Inserts the specified element into this queue, if another thread is - * waiting to receive it. - * - * @param e the element to add - * @return <tt>true</tt> if the element was added to this queue, else - * <tt>false</tt> - * @throws NullPointerException if the specified element is null - */ - public boolean offer(E e) { - if (e == null) throw new NullPointerException(); - return transferer.transfer(e, true, 0) != null; - } - - /** - * Retrieves and removes the head of this queue, waiting if necessary - * for another thread to insert it. - * - * @return the head of this queue - * @throws InterruptedException {@inheritDoc} - */ - public E take() throws InterruptedException { - Object e = transferer.transfer(null, false, 0); - if (e != null) - return (E)e; - Thread.interrupted(); - throw new InterruptedException(); - } - - /** - * Retrieves and removes the head of this queue, waiting - * if necessary up to the specified wait time, for another thread - * to insert it. - * - * @return the head of this queue, or <tt>null</tt> if the - * specified waiting time elapses before an element is present. - * @throws InterruptedException {@inheritDoc} - */ - public E poll(long timeout, TimeUnit unit) throws InterruptedException { - Object e = transferer.transfer(null, true, unit.toNanos(timeout)); - if (e != null || !Thread.interrupted()) - return (E)e; - throw new InterruptedException(); - } - - /** - * Retrieves and removes the head of this queue, if another thread - * is currently making an element available. - * - * @return the head of this queue, or <tt>null</tt> if no - * element is available. - */ - public E poll() { - return (E)transferer.transfer(null, true, 0); - } - - /** - * Always returns <tt>true</tt>. - * A <tt>SynchronousQueue</tt> has no internal capacity. - * - * @return <tt>true</tt> - */ - public boolean isEmpty() { - return true; - } - - /** - * Always returns zero. - * A <tt>SynchronousQueue</tt> has no internal capacity. - * - * @return zero. - */ - public int size() { - return 0; - } - - /** - * Always returns zero. - * A <tt>SynchronousQueue</tt> has no internal capacity. - * - * @return zero. - */ - public int remainingCapacity() { - return 0; - } - - /** - * Does nothing. - * A <tt>SynchronousQueue</tt> has no internal capacity. - */ - public void clear() { - } - - /** - * Always returns <tt>false</tt>. - * A <tt>SynchronousQueue</tt> has no internal capacity. - * - * @param o the element - * @return <tt>false</tt> - */ - public boolean contains(Object o) { - return false; - } - - /** - * Always returns <tt>false</tt>. - * A <tt>SynchronousQueue</tt> has no internal capacity. - * - * @param o the element to remove - * @return <tt>false</tt> - */ - public boolean remove(Object o) { - return false; - } - - /** - * Returns <tt>false</tt> unless the given collection is empty. - * A <tt>SynchronousQueue</tt> has no internal capacity. - * - * @param c the collection - * @return <tt>false</tt> unless given collection is empty - */ - public boolean containsAll(Collection<?> c) { - return c.isEmpty(); - } - - /** - * Always returns <tt>false</tt>. - * A <tt>SynchronousQueue</tt> has no internal capacity. - * - * @param c the collection - * @return <tt>false</tt> - */ - public boolean removeAll(Collection<?> c) { - return false; - } - - /** - * Always returns <tt>false</tt>. - * A <tt>SynchronousQueue</tt> has no internal capacity. - * - * @param c the collection - * @return <tt>false</tt> - */ - public boolean retainAll(Collection<?> c) { - return false; - } - - /** - * Always returns <tt>null</tt>. - * A <tt>SynchronousQueue</tt> does not return elements - * unless actively waited on. - * - * @return <tt>null</tt> - */ - public E peek() { - return null; - } - - static class EmptyIterator<E> implements Iterator<E> { - public boolean hasNext() { - return false; - } - public E next() { - throw new NoSuchElementException(); - } - public void remove() { - throw new IllegalStateException(); - } - } - - /** - * Returns an empty iterator in which <tt>hasNext</tt> always returns - * <tt>false</tt>. - * - * @return an empty iterator - */ - public Iterator<E> iterator() { - return new EmptyIterator<E>(); - } - - /** - * Returns a zero-length array. - * @return a zero-length array - */ - public Object[] toArray() { - return new Object[0]; - } - - /** - * Sets the zeroeth element of the specified array to <tt>null</tt> - * (if the array has non-zero length) and returns it. - * - * @param a the array - * @return the specified array - * @throws NullPointerException if the specified array is null - */ - public <T> T[] toArray(T[] a) { - if (a.length > 0) - a[0] = null; - return a; - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - int n = 0; - E e; - while ( (e = poll()) != null) { - c.add(e); - ++n; - } - return n; - } - - /** - * @throws UnsupportedOperationException {@inheritDoc} - * @throws ClassCastException {@inheritDoc} - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public int drainTo(Collection<? super E> c, int maxElements) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - int n = 0; - E e; - while (n < maxElements && (e = poll()) != null) { - c.add(e); - ++n; - } - return n; - } - - /* - * To cope with serialization strategy in the 1.5 version of - * SynchronousQueue, we declare some unused classes and fields - * that exist solely to enable serializability across versions. - * These fields are never used, so are initialized only if this - * object is ever serialized or deserialized. - */ - - static class WaitQueue implements java.io.Serializable { } - static class LifoWaitQueue extends WaitQueue { - private static final long serialVersionUID = -3633113410248163686L; - } - static class FifoWaitQueue extends WaitQueue { - private static final long serialVersionUID = -3623113410248163686L; - } - private ReentrantLock qlock; - private WaitQueue waitingProducers; - private WaitQueue waitingConsumers; - - /** - * Save the state to a stream (that is, serialize it). - * - * @param s the stream - */ - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - boolean fair = transferer instanceof TransferQueue; - if (fair) { - qlock = new ReentrantLock(true); - waitingProducers = new FifoWaitQueue(); - waitingConsumers = new FifoWaitQueue(); - } - else { - qlock = new ReentrantLock(); - waitingProducers = new LifoWaitQueue(); - waitingConsumers = new LifoWaitQueue(); - } - s.defaultWriteObject(); - } - - private void readObject(final java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); - if (waitingProducers instanceof FifoWaitQueue) - transferer = new TransferQueue(); - else - transferer = new TransferStack(); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ThreadFactory.java b/libjava/classpath/external/jsr166/java/util/concurrent/ThreadFactory.java deleted file mode 100644 index eca8dce..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ThreadFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * An object that creates new threads on demand. Using thread factories - * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread}, - * enabling applications to use special thread subclasses, priorities, etc. - * - * <p> - * The simplest implementation of this interface is just: - * <pre> - * class SimpleThreadFactory implements ThreadFactory { - * public Thread newThread(Runnable r) { - * return new Thread(r); - * } - * } - * </pre> - * - * The {@link Executors#defaultThreadFactory} method provides a more - * useful simple implementation, that sets the created thread context - * to known values before returning it. - * @since 1.5 - * @author Doug Lea - */ -public interface ThreadFactory { - - /** - * Constructs a new <tt>Thread</tt>. Implementations may also initialize - * priority, name, daemon status, <tt>ThreadGroup</tt>, etc. - * - * @param r a runnable to be executed by new thread instance - * @return constructed thread - */ - Thread newThread(Runnable r); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ThreadPoolExecutor.java b/libjava/classpath/external/jsr166/java/util/concurrent/ThreadPoolExecutor.java deleted file mode 100644 index e303f14..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/ThreadPoolExecutor.java +++ /dev/null @@ -1,1605 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; -import java.util.concurrent.locks.*; -import java.util.*; - -/** - * An {@link ExecutorService} that executes each submitted task using - * one of possibly several pooled threads, normally configured - * using {@link Executors} factory methods. - * - * <p>Thread pools address two different problems: they usually - * provide improved performance when executing large numbers of - * asynchronous tasks, due to reduced per-task invocation overhead, - * and they provide a means of bounding and managing the resources, - * including threads, consumed when executing a collection of tasks. - * Each <tt>ThreadPoolExecutor</tt> also maintains some basic - * statistics, such as the number of completed tasks. - * - * <p>To be useful across a wide range of contexts, this class - * provides many adjustable parameters and extensibility - * hooks. However, programmers are urged to use the more convenient - * {@link Executors} factory methods {@link - * Executors#newCachedThreadPool} (unbounded thread pool, with - * automatic thread reclamation), {@link Executors#newFixedThreadPool} - * (fixed size thread pool) and {@link - * Executors#newSingleThreadExecutor} (single background thread), that - * preconfigure settings for the most common usage - * scenarios. Otherwise, use the following guide when manually - * configuring and tuning this class: - * - * <dl> - * - * <dt>Core and maximum pool sizes</dt> - * - * <dd>A <tt>ThreadPoolExecutor</tt> will automatically adjust the - * pool size - * (see {@link ThreadPoolExecutor#getPoolSize}) - * according to the bounds set by corePoolSize - * (see {@link ThreadPoolExecutor#getCorePoolSize}) - * and - * maximumPoolSize - * (see {@link ThreadPoolExecutor#getMaximumPoolSize}). - * When a new task is submitted in method {@link - * ThreadPoolExecutor#execute}, and fewer than corePoolSize threads - * are running, a new thread is created to handle the request, even if - * other worker threads are idle. If there are more than - * corePoolSize but less than maximumPoolSize threads running, a new - * thread will be created only if the queue is full. By setting - * corePoolSize and maximumPoolSize the same, you create a fixed-size - * thread pool. By setting maximumPoolSize to an essentially unbounded - * value such as <tt>Integer.MAX_VALUE</tt>, you allow the pool to - * accommodate an arbitrary number of concurrent tasks. Most typically, - * core and maximum pool sizes are set only upon construction, but they - * may also be changed dynamically using {@link - * ThreadPoolExecutor#setCorePoolSize} and {@link - * ThreadPoolExecutor#setMaximumPoolSize}. <dd> - * - * <dt> On-demand construction - * - * <dd> By default, even core threads are initially created and - * started only when new tasks arrive, but this can be overridden - * dynamically using method {@link - * ThreadPoolExecutor#prestartCoreThread} or - * {@link ThreadPoolExecutor#prestartAllCoreThreads}. - * You probably want to prestart threads if you construct the - * pool with a non-empty queue. </dd> - * - * <dt>Creating new threads</dt> - * - * <dd>New threads are created using a {@link - * java.util.concurrent.ThreadFactory}. If not otherwise specified, a - * {@link Executors#defaultThreadFactory} is used, that creates threads to all - * be in the same {@link ThreadGroup} and with the same - * <tt>NORM_PRIORITY</tt> priority and non-daemon status. By supplying - * a different ThreadFactory, you can alter the thread's name, thread - * group, priority, daemon status, etc. If a <tt>ThreadFactory</tt> fails to create - * a thread when asked by returning null from <tt>newThread</tt>, - * the executor will continue, but might - * not be able to execute any tasks. </dd> - * - * <dt>Keep-alive times</dt> - * - * <dd>If the pool currently has more than corePoolSize threads, - * excess threads will be terminated if they have been idle for more - * than the keepAliveTime (see {@link - * ThreadPoolExecutor#getKeepAliveTime}). This provides a means of - * reducing resource consumption when the pool is not being actively - * used. If the pool becomes more active later, new threads will be - * constructed. This parameter can also be changed dynamically using - * method {@link ThreadPoolExecutor#setKeepAliveTime}. Using a value - * of <tt>Long.MAX_VALUE</tt> {@link TimeUnit#NANOSECONDS} effectively - * disables idle threads from ever terminating prior to shut down. By - * default, the keep-alive policy applies only when there are more - * than corePoolSizeThreads. But method {@link - * ThreadPoolExecutor#allowCoreThreadTimeOut} can be used to apply - * this time-out policy to core threads as well, so long as - * the keepAliveTime value is non-zero. </dd> - * - * <dt>Queuing</dt> - * - * <dd>Any {@link BlockingQueue} may be used to transfer and hold - * submitted tasks. The use of this queue interacts with pool sizing: - * - * <ul> - * - * <li> If fewer than corePoolSize threads are running, the Executor - * always prefers adding a new thread - * rather than queuing.</li> - * - * <li> If corePoolSize or more threads are running, the Executor - * always prefers queuing a request rather than adding a new - * thread.</li> - * - * <li> If a request cannot be queued, a new thread is created unless - * this would exceed maximumPoolSize, in which case, the task will be - * rejected.</li> - * - * </ul> - * - * There are three general strategies for queuing: - * <ol> - * - * <li> <em> Direct handoffs.</em> A good default choice for a work - * queue is a {@link SynchronousQueue} that hands off tasks to threads - * without otherwise holding them. Here, an attempt to queue a task - * will fail if no threads are immediately available to run it, so a - * new thread will be constructed. This policy avoids lockups when - * handling sets of requests that might have internal dependencies. - * Direct handoffs generally require unbounded maximumPoolSizes to - * avoid rejection of new submitted tasks. This in turn admits the - * possibility of unbounded thread growth when commands continue to - * arrive on average faster than they can be processed. </li> - * - * <li><em> Unbounded queues.</em> Using an unbounded queue (for - * example a {@link LinkedBlockingQueue} without a predefined - * capacity) will cause new tasks to wait in the queue when all - * corePoolSize threads are busy. Thus, no more than corePoolSize - * threads will ever be created. (And the value of the maximumPoolSize - * therefore doesn't have any effect.) This may be appropriate when - * each task is completely independent of others, so tasks cannot - * affect each others execution; for example, in a web page server. - * While this style of queuing can be useful in smoothing out - * transient bursts of requests, it admits the possibility of - * unbounded work queue growth when commands continue to arrive on - * average faster than they can be processed. </li> - * - * <li><em>Bounded queues.</em> A bounded queue (for example, an - * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when - * used with finite maximumPoolSizes, but can be more difficult to - * tune and control. Queue sizes and maximum pool sizes may be traded - * off for each other: Using large queues and small pools minimizes - * CPU usage, OS resources, and context-switching overhead, but can - * lead to artificially low throughput. If tasks frequently block (for - * example if they are I/O bound), a system may be able to schedule - * time for more threads than you otherwise allow. Use of small queues - * generally requires larger pool sizes, which keeps CPUs busier but - * may encounter unacceptable scheduling overhead, which also - * decreases throughput. </li> - * - * </ol> - * - * </dd> - * - * <dt>Rejected tasks</dt> - * - * <dd> New tasks submitted in method {@link - * ThreadPoolExecutor#execute} will be <em>rejected</em> when the - * Executor has been shut down, and also when the Executor uses finite - * bounds for both maximum threads and work queue capacity, and is - * saturated. In either case, the <tt>execute</tt> method invokes the - * {@link RejectedExecutionHandler#rejectedExecution} method of its - * {@link RejectedExecutionHandler}. Four predefined handler policies - * are provided: - * - * <ol> - * - * <li> In the - * default {@link ThreadPoolExecutor.AbortPolicy}, the handler throws a - * runtime {@link RejectedExecutionException} upon rejection. </li> - * - * <li> In {@link - * ThreadPoolExecutor.CallerRunsPolicy}, the thread that invokes - * <tt>execute</tt> itself runs the task. This provides a simple - * feedback control mechanism that will slow down the rate that new - * tasks are submitted. </li> - * - * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, - * a task that cannot be executed is simply dropped. </li> - * - * <li>In {@link - * ThreadPoolExecutor.DiscardOldestPolicy}, if the executor is not - * shut down, the task at the head of the work queue is dropped, and - * then execution is retried (which can fail again, causing this to be - * repeated.) </li> - * - * </ol> - * - * It is possible to define and use other kinds of {@link - * RejectedExecutionHandler} classes. Doing so requires some care - * especially when policies are designed to work only under particular - * capacity or queuing policies. </dd> - * - * <dt>Hook methods</dt> - * - * <dd>This class provides <tt>protected</tt> overridable {@link - * ThreadPoolExecutor#beforeExecute} and {@link - * ThreadPoolExecutor#afterExecute} methods that are called before and - * after execution of each task. These can be used to manipulate the - * execution environment; for example, reinitializing ThreadLocals, - * gathering statistics, or adding log entries. Additionally, method - * {@link ThreadPoolExecutor#terminated} can be overridden to perform - * any special processing that needs to be done once the Executor has - * fully terminated. - * - * <p>If hook or callback methods throw - * exceptions, internal worker threads may in turn fail and - * abruptly terminate.</dd> - * - * <dt>Queue maintenance</dt> - * - * <dd> Method {@link ThreadPoolExecutor#getQueue} allows access to - * the work queue for purposes of monitoring and debugging. Use of - * this method for any other purpose is strongly discouraged. Two - * supplied methods, {@link ThreadPoolExecutor#remove} and {@link - * ThreadPoolExecutor#purge} are available to assist in storage - * reclamation when large numbers of queued tasks become - * cancelled.</dd> - * - * <dt>Finalization</dt> - * - * <dd> A pool that is no longer referenced in a program <em>AND</em> - * has no remaining threads will be <tt>shutdown</tt> - * automatically. If you would like to ensure that unreferenced pools - * are reclaimed even if users forget to call {@link - * ThreadPoolExecutor#shutdown}, then you must arrange that unused - * threads eventually die, by setting appropriate keep-alive times, - * using a lower bound of zero core threads and/or setting {@link - * ThreadPoolExecutor#allowCoreThreadTimeOut}. </dd> </dl> - * - * <p> <b>Extension example</b>. Most extensions of this class - * override one or more of the protected hook methods. For example, - * here is a subclass that adds a simple pause/resume feature: - * - * <pre> - * class PausableThreadPoolExecutor extends ThreadPoolExecutor { - * private boolean isPaused; - * private ReentrantLock pauseLock = new ReentrantLock(); - * private Condition unpaused = pauseLock.newCondition(); - * - * public PausableThreadPoolExecutor(...) { super(...); } - * - * protected void beforeExecute(Thread t, Runnable r) { - * super.beforeExecute(t, r); - * pauseLock.lock(); - * try { - * while (isPaused) unpaused.await(); - * } catch (InterruptedException ie) { - * t.interrupt(); - * } finally { - * pauseLock.unlock(); - * } - * } - * - * public void pause() { - * pauseLock.lock(); - * try { - * isPaused = true; - * } finally { - * pauseLock.unlock(); - * } - * } - * - * public void resume() { - * pauseLock.lock(); - * try { - * isPaused = false; - * unpaused.signalAll(); - * } finally { - * pauseLock.unlock(); - * } - * } - * } - * </pre> - * @since 1.5 - * @author Doug Lea - */ -public class ThreadPoolExecutor extends AbstractExecutorService { - /** - * Only used to force toArray() to produce a Runnable[]. - */ - private static final Runnable[] EMPTY_RUNNABLE_ARRAY = new Runnable[0]; - - /** - * Permission for checking shutdown - */ - private static final RuntimePermission shutdownPerm = - new RuntimePermission("modifyThread"); - - /** - * Queue used for holding tasks and handing off to worker threads. - */ - private final BlockingQueue<Runnable> workQueue; - - /** - * Lock held on updates to poolSize, corePoolSize, maximumPoolSize, and - * workers set. - */ - private final ReentrantLock mainLock = new ReentrantLock(); - - /** - * Wait condition to support awaitTermination - */ - private final Condition termination = mainLock.newCondition(); - - /** - * Set containing all worker threads in pool. - */ - private final HashSet<Worker> workers = new HashSet<Worker>(); - - /** - * Timeout in nanoseconds for idle threads waiting for work. - * Threads use this timeout only when there are more than - * corePoolSize present. Otherwise they wait forever for new work. - */ - private volatile long keepAliveTime; - - /** - * If false (default) core threads stay alive even when idle. - * If true, core threads use keepAliveTime to time out waiting for work. - */ - private volatile boolean allowCoreThreadTimeOut; - - /** - * Core pool size, updated only while holding mainLock, - * but volatile to allow concurrent readability even - * during updates. - */ - private volatile int corePoolSize; - - /** - * Maximum pool size, updated only while holding mainLock - * but volatile to allow concurrent readability even - * during updates. - */ - private volatile int maximumPoolSize; - - /** - * Current pool size, updated only while holding mainLock - * but volatile to allow concurrent readability even - * during updates. - */ - private volatile int poolSize; - - /** - * Lifecycle state - */ - volatile int runState; - - // Special values for runState - /** Normal, not-shutdown mode */ - static final int RUNNING = 0; - /** Controlled shutdown mode */ - static final int SHUTDOWN = 1; - /** Immediate shutdown mode */ - static final int STOP = 2; - /** Final state */ - static final int TERMINATED = 3; - - /** - * Handler called when saturated or shutdown in execute. - */ - private volatile RejectedExecutionHandler handler; - - /** - * Factory for new threads. - */ - private volatile ThreadFactory threadFactory; - - /** - * Tracks largest attained pool size. - */ - private int largestPoolSize; - - /** - * Counter for completed tasks. Updated only on termination of - * worker threads. - */ - private long completedTaskCount; - - /** - * The default rejected execution handler - */ - private static final RejectedExecutionHandler defaultHandler = - new AbortPolicy(); - - /** - * Invokes the rejected execution handler for the given command. - */ - void reject(Runnable command) { - handler.rejectedExecution(command, this); - } - - /** - * Creates and returns a new thread running firstTask as its first - * task. Call only while holding mainLock. - * @param firstTask the task the new thread should run first (or - * null if none) - * @return the new thread, or null if threadFactory fails to create thread - */ - private Thread addThread(Runnable firstTask) { - if (runState == TERMINATED) // Don't create thread if terminated - return null; - Worker w = new Worker(firstTask); - Thread t = threadFactory.newThread(w); - if (t != null) { - w.thread = t; - workers.add(w); - int nt = ++poolSize; - if (nt > largestPoolSize) - largestPoolSize = nt; - } - return t; - } - - /** - * Creates and starts a new thread running firstTask as its first - * task, only if fewer than corePoolSize threads are running. - * @param firstTask the task the new thread should run first (or - * null if none) - * @return true if successful. - */ - private boolean addIfUnderCorePoolSize(Runnable firstTask) { - Thread t = null; - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - if (poolSize < corePoolSize) - t = addThread(firstTask); - } finally { - mainLock.unlock(); - } - if (t == null) - return false; - t.start(); - return true; - } - - /** - * Creates and starts a new thread only if fewer than maximumPoolSize - * threads are running. The new thread runs as its first task the - * next task in queue, or if there is none, the given task. - * @param firstTask the task the new thread should run first (or - * null if none) - * @return 0 if a new thread cannot be created, a positive number - * if firstTask will be run in a new thread, or a negative number - * if a new thread was created but is running some other task, in - * which case the caller must try some other way to run firstTask - * (perhaps by calling this method again). - */ - private int addIfUnderMaximumPoolSize(Runnable firstTask) { - Thread t = null; - int status = 0; - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - if (poolSize < maximumPoolSize) { - Runnable next = workQueue.poll(); - if (next == null) { - next = firstTask; - status = 1; - } else - status = -1; - t = addThread(next); - } - } finally { - mainLock.unlock(); - } - if (t == null) - return 0; - t.start(); - return status; - } - - - /** - * Gets the next task for a worker thread to run. - * @return the task - */ - Runnable getTask() { - for (;;) { - try { - switch (runState) { - case RUNNING: { - // untimed wait if core and not allowing core timeout - if (poolSize <= corePoolSize && !allowCoreThreadTimeOut) - return workQueue.take(); - - long timeout = keepAliveTime; - if (timeout <= 0) // die immediately for 0 timeout - return null; - Runnable r = workQueue.poll(timeout, TimeUnit.NANOSECONDS); - if (r != null) - return r; - if (poolSize > corePoolSize || allowCoreThreadTimeOut) - return null; // timed out - // Else, after timeout, the pool shrank. Retry - break; - } - - case SHUTDOWN: { - // Help drain queue - Runnable r = workQueue.poll(); - if (r != null) - return r; - - // Check if can terminate - if (workQueue.isEmpty()) { - interruptIdleWorkers(); - return null; - } - - // Else there could still be delayed tasks in queue. - return workQueue.take(); - } - - case STOP: - return null; - default: - assert false; - } - } catch (InterruptedException ie) { - // On interruption, re-check runstate - } - } - } - - /** - * Wakes up all threads that might be waiting for tasks. - */ - void interruptIdleWorkers() { - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - for (Worker w : workers) - w.interruptIfIdle(); - } finally { - mainLock.unlock(); - } - } - - /** - * Performs bookkeeping for a terminated worker thread. - * @param w the worker - */ - void workerDone(Worker w) { - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - completedTaskCount += w.completedTasks; - workers.remove(w); - if (--poolSize > 0) - return; - - // Else, this is the last thread. Deal with potential shutdown. - - int state = runState; - assert state != TERMINATED; - - if (state != STOP) { - // If there are queued tasks but no threads, create - // replacement thread. We must create it initially - // idle to avoid orphaned tasks in case addThread - // fails. This also handles case of delayed tasks - // that will sometime later become runnable. - if (!workQueue.isEmpty()) { - Thread t = addThread(null); - if (t != null) - t.start(); - return; - } - - // Otherwise, we can exit without replacement - if (state == RUNNING) - return; - } - - // Either state is STOP, or state is SHUTDOWN and there is - // no work to do. So we can terminate. - termination.signalAll(); - runState = TERMINATED; - // fall through to call terminate() outside of lock. - } finally { - mainLock.unlock(); - } - - assert runState == TERMINATED; - terminated(); - } - - /** - * Worker threads - */ - private class Worker implements Runnable { - - /** - * The runLock is acquired and released surrounding each task - * execution. It mainly protects against interrupts that are - * intended to cancel the worker thread from instead - * interrupting the task being run. - */ - private final ReentrantLock runLock = new ReentrantLock(); - - /** - * Initial task to run before entering run loop - */ - private Runnable firstTask; - - /** - * Per thread completed task counter; accumulated - * into completedTaskCount upon termination. - */ - volatile long completedTasks; - - /** - * Thread this worker is running in. Acts as a final field, - * but cannot be set until thread is created. - */ - Thread thread; - - Worker(Runnable firstTask) { - this.firstTask = firstTask; - } - - boolean isActive() { - return runLock.isLocked(); - } - - /** - * Interrupts thread if not running a task. - */ - void interruptIfIdle() { - final ReentrantLock runLock = this.runLock; - if (runLock.tryLock()) { - try { - thread.interrupt(); - } finally { - runLock.unlock(); - } - } - } - - /** - * Interrupts thread even if running a task. - */ - void interruptNow() { - thread.interrupt(); - } - - /** - * Runs a single task between before/after methods. - */ - private void runTask(Runnable task) { - final ReentrantLock runLock = this.runLock; - runLock.lock(); - try { - // If not shutting down then clear an outstanding interrupt. - if (runState != STOP && - Thread.interrupted() && - runState == STOP) // Re-interrupt if stopped after clearing - thread.interrupt(); - boolean ran = false; - beforeExecute(thread, task); - try { - task.run(); - ran = true; - afterExecute(task, null); - ++completedTasks; - } catch (RuntimeException ex) { - if (!ran) - afterExecute(task, ex); - // Else the exception occurred within - // afterExecute itself in which case we don't - // want to call it again. - throw ex; - } - } finally { - runLock.unlock(); - } - } - - /** - * Main run loop - */ - public void run() { - try { - Runnable task = firstTask; - firstTask = null; - while (task != null || (task = getTask()) != null) { - runTask(task); - task = null; // unnecessary but can help GC - } - } finally { - workerDone(this); - } - } - } - - // Public methods - - /** - * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial - * parameters and default thread factory and rejected execution handler. - * It may be more convenient to use one of the {@link Executors} factory - * methods instead of this general purpose constructor. - * - * @param corePoolSize the number of threads to keep in the - * pool, even if they are idle. - * @param maximumPoolSize the maximum number of threads to allow in the - * pool. - * @param keepAliveTime when the number of threads is greater than - * the core, this is the maximum time that excess idle threads - * will wait for new tasks before terminating. - * @param unit the time unit for the keepAliveTime - * argument. - * @param workQueue the queue to use for holding tasks before they - * are executed. This queue will hold only the <tt>Runnable</tt> - * tasks submitted by the <tt>execute</tt> method. - * @throws IllegalArgumentException if corePoolSize, or - * keepAliveTime less than zero, or if maximumPoolSize less than or - * equal to zero, or if corePoolSize greater than maximumPoolSize. - * @throws NullPointerException if <tt>workQueue</tt> is null - */ - public ThreadPoolExecutor(int corePoolSize, - int maximumPoolSize, - long keepAliveTime, - TimeUnit unit, - BlockingQueue<Runnable> workQueue) { - this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, - Executors.defaultThreadFactory(), defaultHandler); - } - - /** - * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial - * parameters and default rejected execution handler. - * - * @param corePoolSize the number of threads to keep in the - * pool, even if they are idle. - * @param maximumPoolSize the maximum number of threads to allow in the - * pool. - * @param keepAliveTime when the number of threads is greater than - * the core, this is the maximum time that excess idle threads - * will wait for new tasks before terminating. - * @param unit the time unit for the keepAliveTime - * argument. - * @param workQueue the queue to use for holding tasks before they - * are executed. This queue will hold only the <tt>Runnable</tt> - * tasks submitted by the <tt>execute</tt> method. - * @param threadFactory the factory to use when the executor - * creates a new thread. - * @throws IllegalArgumentException if corePoolSize, or - * keepAliveTime less than zero, or if maximumPoolSize less than or - * equal to zero, or if corePoolSize greater than maximumPoolSize. - * @throws NullPointerException if <tt>workQueue</tt> - * or <tt>threadFactory</tt> are null. - */ - public ThreadPoolExecutor(int corePoolSize, - int maximumPoolSize, - long keepAliveTime, - TimeUnit unit, - BlockingQueue<Runnable> workQueue, - ThreadFactory threadFactory) { - this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, - threadFactory, defaultHandler); - } - - /** - * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial - * parameters and default thread factory. - * - * @param corePoolSize the number of threads to keep in the - * pool, even if they are idle. - * @param maximumPoolSize the maximum number of threads to allow in the - * pool. - * @param keepAliveTime when the number of threads is greater than - * the core, this is the maximum time that excess idle threads - * will wait for new tasks before terminating. - * @param unit the time unit for the keepAliveTime - * argument. - * @param workQueue the queue to use for holding tasks before they - * are executed. This queue will hold only the <tt>Runnable</tt> - * tasks submitted by the <tt>execute</tt> method. - * @param handler the handler to use when execution is blocked - * because the thread bounds and queue capacities are reached. - * @throws IllegalArgumentException if corePoolSize, or - * keepAliveTime less than zero, or if maximumPoolSize less than or - * equal to zero, or if corePoolSize greater than maximumPoolSize. - * @throws NullPointerException if <tt>workQueue</tt> - * or <tt>handler</tt> are null. - */ - public ThreadPoolExecutor(int corePoolSize, - int maximumPoolSize, - long keepAliveTime, - TimeUnit unit, - BlockingQueue<Runnable> workQueue, - RejectedExecutionHandler handler) { - this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, - Executors.defaultThreadFactory(), handler); - } - - /** - * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial - * parameters. - * - * @param corePoolSize the number of threads to keep in the - * pool, even if they are idle. - * @param maximumPoolSize the maximum number of threads to allow in the - * pool. - * @param keepAliveTime when the number of threads is greater than - * the core, this is the maximum time that excess idle threads - * will wait for new tasks before terminating. - * @param unit the time unit for the keepAliveTime - * argument. - * @param workQueue the queue to use for holding tasks before they - * are executed. This queue will hold only the <tt>Runnable</tt> - * tasks submitted by the <tt>execute</tt> method. - * @param threadFactory the factory to use when the executor - * creates a new thread. - * @param handler the handler to use when execution is blocked - * because the thread bounds and queue capacities are reached. - * @throws IllegalArgumentException if corePoolSize, or - * keepAliveTime less than zero, or if maximumPoolSize less than or - * equal to zero, or if corePoolSize greater than maximumPoolSize. - * @throws NullPointerException if <tt>workQueue</tt> - * or <tt>threadFactory</tt> or <tt>handler</tt> are null. - */ - public ThreadPoolExecutor(int corePoolSize, - int maximumPoolSize, - long keepAliveTime, - TimeUnit unit, - BlockingQueue<Runnable> workQueue, - ThreadFactory threadFactory, - RejectedExecutionHandler handler) { - if (corePoolSize < 0 || - maximumPoolSize <= 0 || - maximumPoolSize < corePoolSize || - keepAliveTime < 0) - throw new IllegalArgumentException(); - if (workQueue == null || threadFactory == null || handler == null) - throw new NullPointerException(); - this.corePoolSize = corePoolSize; - this.maximumPoolSize = maximumPoolSize; - this.workQueue = workQueue; - this.keepAliveTime = unit.toNanos(keepAliveTime); - this.threadFactory = threadFactory; - this.handler = handler; - } - - - /** - * Executes the given task sometime in the future. The task - * may execute in a new thread or in an existing pooled thread. - * - * If the task cannot be submitted for execution, either because this - * executor has been shutdown or because its capacity has been reached, - * the task is handled by the current <tt>RejectedExecutionHandler</tt>. - * - * @param command the task to execute - * @throws RejectedExecutionException at discretion of - * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted - * for execution - * @throws NullPointerException if command is null - */ - public void execute(Runnable command) { - if (command == null) - throw new NullPointerException(); - for (;;) { - if (runState != RUNNING) { - reject(command); - return; - } - if (poolSize < corePoolSize && addIfUnderCorePoolSize(command)) - return; - if (workQueue.offer(command)) - return; - int status = addIfUnderMaximumPoolSize(command); - if (status > 0) // created new thread - return; - if (status == 0) { // failed to create thread - reject(command); - return; - } - // Retry if created a new thread but it is busy with another task - } - } - - /** - * Initiates an orderly shutdown in which previously submitted - * tasks are executed, but no new tasks will be - * accepted. Invocation has no additional effect if already shut - * down. - * @throws SecurityException if a security manager exists and - * shutting down this ExecutorService may manipulate threads that - * the caller is not permitted to modify because it does not hold - * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>, - * or the security manager's <tt>checkAccess</tt> method denies access. - */ - public void shutdown() { - // Fail if caller doesn't have modifyThread permission. - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkPermission(shutdownPerm); - - boolean fullyTerminated = false; - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - if (workers.size() > 0) { - // Check if caller can modify worker threads. This - // might not be true even if passed above check, if - // the SecurityManager treats some threads specially. - if (security != null) { - for (Worker w: workers) - security.checkAccess(w.thread); - } - - int state = runState; - if (state == RUNNING) // don't override shutdownNow - runState = SHUTDOWN; - - try { - for (Worker w: workers) - w.interruptIfIdle(); - } catch (SecurityException se) { - // If SecurityManager allows above checks, but - // then unexpectedly throws exception when - // interrupting threads (which it ought not do), - // back out as cleanly as we can. Some threads may - // have been killed but we remain in non-shutdown - // state. - runState = state; - throw se; - } - } - else { // If no workers, trigger full termination now - fullyTerminated = true; - runState = TERMINATED; - termination.signalAll(); - } - } finally { - mainLock.unlock(); - } - if (fullyTerminated) - terminated(); - } - - - /** - * Attempts to stop all actively executing tasks, halts the - * processing of waiting tasks, and returns a list of the tasks - * that were awaiting execution. - * - * <p>There are no guarantees beyond best-effort attempts to stop - * processing actively executing tasks. This implementation - * cancels tasks via {@link Thread#interrupt}, so any task that - * fails to respond to interrupts may never terminate. - * - * @return list of tasks that never commenced execution - * @throws SecurityException if a security manager exists and - * shutting down this ExecutorService may manipulate threads that - * the caller is not permitted to modify because it does not hold - * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>, - * or the security manager's <tt>checkAccess</tt> method denies access. - */ - public List<Runnable> shutdownNow() { - // Almost the same code as shutdown() - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkPermission(shutdownPerm); - - boolean fullyTerminated = false; - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - if (workers.size() > 0) { - if (security != null) { - for (Worker w: workers) - security.checkAccess(w.thread); - } - - int state = runState; - if (state != TERMINATED) - runState = STOP; - try { - for (Worker w : workers) - w.interruptNow(); - } catch (SecurityException se) { - runState = state; // back out; - throw se; - } - } - else { // If no workers, trigger full termination now - fullyTerminated = true; - runState = TERMINATED; - termination.signalAll(); - } - } finally { - mainLock.unlock(); - } - if (fullyTerminated) - terminated(); - return Arrays.asList(workQueue.toArray(EMPTY_RUNNABLE_ARRAY)); - } - - public boolean isShutdown() { - return runState != RUNNING; - } - - /** - * Returns true if this executor is in the process of terminating - * after <tt>shutdown</tt> or <tt>shutdownNow</tt> but has not - * completely terminated. This method may be useful for - * debugging. A return of <tt>true</tt> reported a sufficient - * period after shutdown may indicate that submitted tasks have - * ignored or suppressed interruption, causing this executor not - * to properly terminate. - * @return true if terminating but not yet terminated. - */ - public boolean isTerminating() { - return runState == STOP; - } - - public boolean isTerminated() { - return runState == TERMINATED; - } - - public boolean awaitTermination(long timeout, TimeUnit unit) - throws InterruptedException { - long nanos = unit.toNanos(timeout); - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - for (;;) { - if (runState == TERMINATED) - return true; - if (nanos <= 0) - return false; - nanos = termination.awaitNanos(nanos); - } - } finally { - mainLock.unlock(); - } - } - - /** - * Invokes <tt>shutdown</tt> when this executor is no longer - * referenced. - */ - protected void finalize() { - shutdown(); - } - - /** - * Sets the thread factory used to create new threads. - * - * @param threadFactory the new thread factory - * @throws NullPointerException if threadFactory is null - * @see #getThreadFactory - */ - public void setThreadFactory(ThreadFactory threadFactory) { - if (threadFactory == null) - throw new NullPointerException(); - this.threadFactory = threadFactory; - } - - /** - * Returns the thread factory used to create new threads. - * - * @return the current thread factory - * @see #setThreadFactory - */ - public ThreadFactory getThreadFactory() { - return threadFactory; - } - - /** - * Sets a new handler for unexecutable tasks. - * - * @param handler the new handler - * @throws NullPointerException if handler is null - * @see #getRejectedExecutionHandler - */ - public void setRejectedExecutionHandler(RejectedExecutionHandler handler) { - if (handler == null) - throw new NullPointerException(); - this.handler = handler; - } - - /** - * Returns the current handler for unexecutable tasks. - * - * @return the current handler - * @see #setRejectedExecutionHandler - */ - public RejectedExecutionHandler getRejectedExecutionHandler() { - return handler; - } - - /** - * Returns the task queue used by this executor. Access to the - * task queue is intended primarily for debugging and monitoring. - * This queue may be in active use. Retrieving the task queue - * does not prevent queued tasks from executing. - * - * @return the task queue - */ - public BlockingQueue<Runnable> getQueue() { - return workQueue; - } - - /** - * Removes this task from the executor's internal queue if it is - * present, thus causing it not to be run if it has not already - * started. - * - * <p> This method may be useful as one part of a cancellation - * scheme. It may fail to remove tasks that have been converted - * into other forms before being placed on the internal queue. For - * example, a task entered using <tt>submit</tt> might be - * converted into a form that maintains <tt>Future</tt> status. - * However, in such cases, method {@link ThreadPoolExecutor#purge} - * may be used to remove those Futures that have been cancelled. - * - * @param task the task to remove - * @return true if the task was removed - */ - public boolean remove(Runnable task) { - return getQueue().remove(task); - } - - - /** - * Tries to remove from the work queue all {@link Future} - * tasks that have been cancelled. This method can be useful as a - * storage reclamation operation, that has no other impact on - * functionality. Cancelled tasks are never executed, but may - * accumulate in work queues until worker threads can actively - * remove them. Invoking this method instead tries to remove them now. - * However, this method may fail to remove tasks in - * the presence of interference by other threads. - */ - public void purge() { - // Fail if we encounter interference during traversal - try { - Iterator<Runnable> it = getQueue().iterator(); - while (it.hasNext()) { - Runnable r = it.next(); - if (r instanceof Future<?>) { - Future<?> c = (Future<?>)r; - if (c.isCancelled()) - it.remove(); - } - } - } - catch (ConcurrentModificationException ex) { - return; - } - } - - /** - * Sets the core number of threads. This overrides any value set - * in the constructor. If the new value is smaller than the - * current value, excess existing threads will be terminated when - * they next become idle. If larger, new threads will, if needed, - * be started to execute any queued tasks. - * - * @param corePoolSize the new core size - * @throws IllegalArgumentException if <tt>corePoolSize</tt> - * less than zero - * @see #getCorePoolSize - */ - public void setCorePoolSize(int corePoolSize) { - if (corePoolSize < 0) - throw new IllegalArgumentException(); - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - int extra = this.corePoolSize - corePoolSize; - this.corePoolSize = corePoolSize; - if (extra < 0) { - int n = workQueue.size(); - // We have to create initially-idle threads here - // because we otherwise have no recourse about - // what to do with a dequeued task if addThread fails. - while (extra++ < 0 && n-- > 0 && poolSize < corePoolSize ) { - Thread t = addThread(null); - if (t != null) - t.start(); - else - break; - } - } - else if (extra > 0 && poolSize > corePoolSize) { - Iterator<Worker> it = workers.iterator(); - while (it.hasNext() && - extra-- > 0 && - poolSize > corePoolSize && - workQueue.remainingCapacity() == 0) - it.next().interruptIfIdle(); - } - } finally { - mainLock.unlock(); - } - } - - /** - * Returns the core number of threads. - * - * @return the core number of threads - * @see #setCorePoolSize - */ - public int getCorePoolSize() { - return corePoolSize; - } - - /** - * Starts a core thread, causing it to idly wait for work. This - * overrides the default policy of starting core threads only when - * new tasks are executed. This method will return <tt>false</tt> - * if all core threads have already been started. - * @return true if a thread was started - */ - public boolean prestartCoreThread() { - return addIfUnderCorePoolSize(null); - } - - /** - * Starts all core threads, causing them to idly wait for work. This - * overrides the default policy of starting core threads only when - * new tasks are executed. - * @return the number of threads started. - */ - public int prestartAllCoreThreads() { - int n = 0; - while (addIfUnderCorePoolSize(null)) - ++n; - return n; - } - - /** - * Returns true if this pool allows core threads to time out and - * terminate if no tasks arrive within the keepAlive time, being - * replaced if needed when new tasks arrive. When true, the same - * keep-alive policy applying to non-core threads applies also to - * core threads. When false (the default), core threads are never - * terminated due to lack of incoming tasks. - * @return <tt>true</tt> if core threads are allowed to time out, - * else <tt>false</tt> - * - * @since 1.6 - */ - public boolean allowsCoreThreadTimeOut() { - return allowCoreThreadTimeOut; - } - - /** - * Sets the policy governing whether core threads may time out and - * terminate if no tasks arrive within the keep-alive time, being - * replaced if needed when new tasks arrive. When false, core - * threads are never terminated due to lack of incoming - * tasks. When true, the same keep-alive policy applying to - * non-core threads applies also to core threads. To avoid - * continual thread replacement, the keep-alive time must be - * greater than zero when setting <tt>true</tt>. This method - * should in general be called before the pool is actively used. - * @param value <tt>true</tt> if should time out, else <tt>false</tt> - * @throws IllegalArgumentException if value is <tt>true</tt> - * and the current keep-alive time is not greater than zero. - * - * @since 1.6 - */ - public void allowCoreThreadTimeOut(boolean value) { - if (value && keepAliveTime <= 0) - throw new IllegalArgumentException("Core threads must have nonzero keep alive times"); - - allowCoreThreadTimeOut = value; - } - - /** - * Sets the maximum allowed number of threads. This overrides any - * value set in the constructor. If the new value is smaller than - * the current value, excess existing threads will be - * terminated when they next become idle. - * - * @param maximumPoolSize the new maximum - * @throws IllegalArgumentException if the new maximum is - * less than or equal to zero, or - * less than the {@linkplain #getCorePoolSize core pool size} - * @see #getMaximumPoolSize - */ - public void setMaximumPoolSize(int maximumPoolSize) { - if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize) - throw new IllegalArgumentException(); - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - int extra = this.maximumPoolSize - maximumPoolSize; - this.maximumPoolSize = maximumPoolSize; - if (extra > 0 && poolSize > maximumPoolSize) { - Iterator<Worker> it = workers.iterator(); - while (it.hasNext() && - extra > 0 && - poolSize > maximumPoolSize) { - it.next().interruptIfIdle(); - --extra; - } - } - } finally { - mainLock.unlock(); - } - } - - /** - * Returns the maximum allowed number of threads. - * - * @return the maximum allowed number of threads - * @see #setMaximumPoolSize - */ - public int getMaximumPoolSize() { - return maximumPoolSize; - } - - /** - * Sets the time limit for which threads may remain idle before - * being terminated. If there are more than the core number of - * threads currently in the pool, after waiting this amount of - * time without processing a task, excess threads will be - * terminated. This overrides any value set in the constructor. - * @param time the time to wait. A time value of zero will cause - * excess threads to terminate immediately after executing tasks. - * @param unit the time unit of the time argument - * @throws IllegalArgumentException if time less than zero or - * if time is zero and allowsCoreThreadTimeOut - * @see #getKeepAliveTime - */ - public void setKeepAliveTime(long time, TimeUnit unit) { - if (time < 0) - throw new IllegalArgumentException(); - if (time == 0 && allowsCoreThreadTimeOut()) - throw new IllegalArgumentException("Core threads must have nonzero keep alive times"); - this.keepAliveTime = unit.toNanos(time); - } - - /** - * Returns the thread keep-alive time, which is the amount of time - * which threads in excess of the core pool size may remain - * idle before being terminated. - * - * @param unit the desired time unit of the result - * @return the time limit - * @see #setKeepAliveTime - */ - public long getKeepAliveTime(TimeUnit unit) { - return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS); - } - - /* Statistics */ - - /** - * Returns the current number of threads in the pool. - * - * @return the number of threads - */ - public int getPoolSize() { - return poolSize; - } - - /** - * Returns the approximate number of threads that are actively - * executing tasks. - * - * @return the number of threads - */ - public int getActiveCount() { - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - int n = 0; - for (Worker w : workers) { - if (w.isActive()) - ++n; - } - return n; - } finally { - mainLock.unlock(); - } - } - - /** - * Returns the largest number of threads that have ever - * simultaneously been in the pool. - * - * @return the number of threads - */ - public int getLargestPoolSize() { - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - return largestPoolSize; - } finally { - mainLock.unlock(); - } - } - - /** - * Returns the approximate total number of tasks that have been - * scheduled for execution. Because the states of tasks and - * threads may change dynamically during computation, the returned - * value is only an approximation, but one that does not ever - * decrease across successive calls. - * - * @return the number of tasks - */ - public long getTaskCount() { - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - long n = completedTaskCount; - for (Worker w : workers) { - n += w.completedTasks; - if (w.isActive()) - ++n; - } - return n + workQueue.size(); - } finally { - mainLock.unlock(); - } - } - - /** - * Returns the approximate total number of tasks that have - * completed execution. Because the states of tasks and threads - * may change dynamically during computation, the returned value - * is only an approximation, but one that does not ever decrease - * across successive calls. - * - * @return the number of tasks - */ - public long getCompletedTaskCount() { - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - long n = completedTaskCount; - for (Worker w : workers) - n += w.completedTasks; - return n; - } finally { - mainLock.unlock(); - } - } - - /** - * Method invoked prior to executing the given Runnable in the - * given thread. This method is invoked by thread <tt>t</tt> that - * will execute task <tt>r</tt>, and may be used to re-initialize - * ThreadLocals, or to perform logging. - * - * <p>This implementation does nothing, but may be customized in - * subclasses. Note: To properly nest multiple overridings, subclasses - * should generally invoke <tt>super.beforeExecute</tt> at the end of - * this method. - * - * @param t the thread that will run task r. - * @param r the task that will be executed. - */ - protected void beforeExecute(Thread t, Runnable r) { } - - /** - * Method invoked upon completion of execution of the given Runnable. - * This method is invoked by the thread that executed the task. If - * non-null, the Throwable is the uncaught <tt>RuntimeException</tt> - * or <tt>Error</tt> that caused execution to terminate abruptly. - * - * <p><b>Note:</b> When actions are enclosed in tasks (such as - * {@link FutureTask}) either explicitly or via methods such as - * <tt>submit</tt>, these task objects catch and maintain - * computational exceptions, and so they do not cause abrupt - * termination, and the internal exceptions are <em>not</em> - * passed to this method. - * - * <p>This implementation does nothing, but may be customized in - * subclasses. Note: To properly nest multiple overridings, subclasses - * should generally invoke <tt>super.afterExecute</tt> at the - * beginning of this method. - * - * @param r the runnable that has completed. - * @param t the exception that caused termination, or null if - * execution completed normally. - */ - protected void afterExecute(Runnable r, Throwable t) { } - - /** - * Method invoked when the Executor has terminated. Default - * implementation does nothing. Note: To properly nest multiple - * overridings, subclasses should generally invoke - * <tt>super.terminated</tt> within this method. - */ - protected void terminated() { } - - /** - * A handler for rejected tasks that runs the rejected task - * directly in the calling thread of the <tt>execute</tt> method, - * unless the executor has been shut down, in which case the task - * is discarded. - */ - public static class CallerRunsPolicy implements RejectedExecutionHandler { - /** - * Creates a <tt>CallerRunsPolicy</tt>. - */ - public CallerRunsPolicy() { } - - /** - * Executes task r in the caller's thread, unless the executor - * has been shut down, in which case the task is discarded. - * @param r the runnable task requested to be executed - * @param e the executor attempting to execute this task - */ - public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { - if (!e.isShutdown()) { - r.run(); - } - } - } - - /** - * A handler for rejected tasks that throws a - * <tt>RejectedExecutionException</tt>. - */ - public static class AbortPolicy implements RejectedExecutionHandler { - /** - * Creates an <tt>AbortPolicy</tt>. - */ - public AbortPolicy() { } - - /** - * Always throws RejectedExecutionException. - * @param r the runnable task requested to be executed - * @param e the executor attempting to execute this task - * @throws RejectedExecutionException always. - */ - public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { - throw new RejectedExecutionException(); - } - } - - /** - * A handler for rejected tasks that silently discards the - * rejected task. - */ - public static class DiscardPolicy implements RejectedExecutionHandler { - /** - * Creates a <tt>DiscardPolicy</tt>. - */ - public DiscardPolicy() { } - - /** - * Does nothing, which has the effect of discarding task r. - * @param r the runnable task requested to be executed - * @param e the executor attempting to execute this task - */ - public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { - } - } - - /** - * A handler for rejected tasks that discards the oldest unhandled - * request and then retries <tt>execute</tt>, unless the executor - * is shut down, in which case the task is discarded. - */ - public static class DiscardOldestPolicy implements RejectedExecutionHandler { - /** - * Creates a <tt>DiscardOldestPolicy</tt> for the given executor. - */ - public DiscardOldestPolicy() { } - - /** - * Obtains and ignores the next task that the executor - * would otherwise execute, if one is immediately available, - * and then retries execution of task r, unless the executor - * is shut down, in which case task r is instead discarded. - * @param r the runnable task requested to be executed - * @param e the executor attempting to execute this task - */ - public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { - if (!e.isShutdown()) { - e.getQueue().poll(); - e.execute(r); - } - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/TimeUnit.java b/libjava/classpath/external/jsr166/java/util/concurrent/TimeUnit.java deleted file mode 100644 index 2cd3d06..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/TimeUnit.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * A <tt>TimeUnit</tt> represents time durations at a given unit of - * granularity and provides utility methods to convert across units, - * and to perform timing and delay operations in these units. A - * <tt>TimeUnit</tt> does not maintain time information, but only - * helps organize and use time representations that may be maintained - * separately across various contexts. A nanosecond is defined as one - * thousandth of a microsecond, a microsecond as one thousandth of a - * millisecond, a millisecond as one thousandth of a second, a minute - * as sixty seconds, an hour as sixty minutes, and a day as twenty four - * hours. - * - * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods - * how a given timing parameter should be interpreted. For example, - * the following code will timeout in 50 milliseconds if the {@link - * java.util.concurrent.locks.Lock lock} is not available: - * - * <pre> Lock lock = ...; - * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ... - * </pre> - * while this code will timeout in 50 seconds: - * <pre> - * Lock lock = ...; - * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ... - * </pre> - * - * Note however, that there is no guarantee that a particular timeout - * implementation will be able to notice the passage of time at the - * same granularity as the given <tt>TimeUnit</tt>. - * - * @since 1.5 - * @author Doug Lea - */ -public enum TimeUnit { - NANOSECONDS { - public long toNanos(long d) { return d; } - public long toMicros(long d) { return d/(C1/C0); } - public long toMillis(long d) { return d/(C2/C0); } - public long toSeconds(long d) { return d/(C3/C0); } - public long toMinutes(long d) { return d/(C4/C0); } - public long toHours(long d) { return d/(C5/C0); } - public long toDays(long d) { return d/(C6/C0); } - public long convert(long d, TimeUnit u) { return u.toNanos(d); } - int excessNanos(long d, long m) { return (int)(d - (m*C2)); } - }, - MICROSECONDS { - public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } - public long toMicros(long d) { return d; } - public long toMillis(long d) { return d/(C2/C1); } - public long toSeconds(long d) { return d/(C3/C1); } - public long toMinutes(long d) { return d/(C4/C1); } - public long toHours(long d) { return d/(C5/C1); } - public long toDays(long d) { return d/(C6/C1); } - public long convert(long d, TimeUnit u) { return u.toMicros(d); } - int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } - }, - MILLISECONDS { - public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); } - public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); } - public long toMillis(long d) { return d; } - public long toSeconds(long d) { return d/(C3/C2); } - public long toMinutes(long d) { return d/(C4/C2); } - public long toHours(long d) { return d/(C5/C2); } - public long toDays(long d) { return d/(C6/C2); } - public long convert(long d, TimeUnit u) { return u.toMillis(d); } - int excessNanos(long d, long m) { return 0; } - }, - SECONDS { - public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); } - public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); } - public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); } - public long toSeconds(long d) { return d; } - public long toMinutes(long d) { return d/(C4/C3); } - public long toHours(long d) { return d/(C5/C3); } - public long toDays(long d) { return d/(C6/C3); } - public long convert(long d, TimeUnit u) { return u.toSeconds(d); } - int excessNanos(long d, long m) { return 0; } - }, - MINUTES { - public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); } - public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); } - public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); } - public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); } - public long toMinutes(long d) { return d; } - public long toHours(long d) { return d/(C5/C4); } - public long toDays(long d) { return d/(C6/C4); } - public long convert(long d, TimeUnit u) { return u.toMinutes(d); } - int excessNanos(long d, long m) { return 0; } - }, - HOURS { - public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); } - public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); } - public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); } - public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); } - public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); } - public long toHours(long d) { return d; } - public long toDays(long d) { return d/(C6/C5); } - public long convert(long d, TimeUnit u) { return u.toHours(d); } - int excessNanos(long d, long m) { return 0; } - }, - DAYS { - public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); } - public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); } - public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); } - public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); } - public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); } - public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); } - public long toDays(long d) { return d; } - public long convert(long d, TimeUnit u) { return u.toDays(d); } - int excessNanos(long d, long m) { return 0; } - }; - - // Handy constants for conversion methods - static final long C0 = 1L; - static final long C1 = C0 * 1000L; - static final long C2 = C1 * 1000L; - static final long C3 = C2 * 1000L; - static final long C4 = C3 * 60L; - static final long C5 = C4 * 60L; - static final long C6 = C5 * 24L; - - static final long MAX = Long.MAX_VALUE; - - /** - * Scale d by m, checking for overflow. - * This has a short name to make above code more readable. - */ - static long x(long d, long m, long over) { - if (d > over) return Long.MAX_VALUE; - if (d < -over) return Long.MIN_VALUE; - return d * m; - } - - // To maintain full signature compatibility with 1.5, and to improve the - // clarity of the generated javadoc (see 6287639: Abstract methods in - // enum classes should not be listed as abstract), method convert - // etc. are not declared abstract but otherwise act as abstract methods. - - /** - * Convert the given time duration in the given unit to this - * unit. Conversions from finer to coarser granularities - * truncate, so lose precision. For example converting - * <tt>999</tt> milliseconds to seconds results in - * <tt>0</tt>. Conversions from coarser to finer granularities - * with arguments that would numerically overflow saturate to - * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt> - * if positive. - * - * <p>For example, to convert 10 minutes to milliseconds, use: - * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt> - * - * @param sourceDuration the time duration in the given <tt>sourceUnit</tt> - * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument - * @return the converted duration in this unit, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. - */ - public long convert(long sourceDuration, TimeUnit sourceUnit) { - throw new AbstractMethodError(); - } - - /** - * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>. - * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. - * @see #convert - */ - public long toNanos(long duration) { - throw new AbstractMethodError(); - } - - /** - * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>. - * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. - * @see #convert - */ - public long toMicros(long duration) { - throw new AbstractMethodError(); - } - - /** - * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>. - * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. - * @see #convert - */ - public long toMillis(long duration) { - throw new AbstractMethodError(); - } - - /** - * Equivalent to <tt>SECONDS.convert(duration, this)</tt>. - * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. - * @see #convert - */ - public long toSeconds(long duration) { - throw new AbstractMethodError(); - } - - /** - * Equivalent to <tt>MINUTES.convert(duration, this)</tt>. - * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. - * @see #convert - * @since 1.6 - */ - public long toMinutes(long duration) { - throw new AbstractMethodError(); - } - - /** - * Equivalent to <tt>HOURS.convert(duration, this)</tt>. - * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. - * @see #convert - * @since 1.6 - */ - public long toHours(long duration) { - throw new AbstractMethodError(); - } - - /** - * Equivalent to <tt>DAYS.convert(duration, this)</tt>. - * @param duration the duration - * @return the converted duration - * @see #convert - * @since 1.6 - */ - public long toDays(long duration) { - throw new AbstractMethodError(); - } - - /** - * Utility to compute the excess-nanosecond argument to wait, - * sleep, join. - * @param d the duration - * @param m the number of milliseconds - * @return the number of nanoseconds - */ - abstract int excessNanos(long d, long m); - - /** - * Performs a timed <tt>Object.wait</tt> using this time unit. - * This is a convenience method that converts timeout arguments - * into the form required by the <tt>Object.wait</tt> method. - * - * <p>For example, you could implement a blocking <tt>poll</tt> - * method (see {@link BlockingQueue#poll BlockingQueue.poll}) - * using: - * - * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException { - * while (empty) { - * unit.timedWait(this, timeout); - * ... - * } - * }</pre> - * - * @param obj the object to wait on - * @param timeout the maximum time to wait. If less than - * or equal to zero, do not wait at all. - * @throws InterruptedException if interrupted while waiting. - * @see Object#wait(long, int) - */ - public void timedWait(Object obj, long timeout) - throws InterruptedException { - if (timeout > 0) { - long ms = toMillis(timeout); - int ns = excessNanos(timeout, ms); - obj.wait(ms, ns); - } - } - - /** - * Performs a timed <tt>Thread.join</tt> using this time unit. - * This is a convenience method that converts time arguments into the - * form required by the <tt>Thread.join</tt> method. - * @param thread the thread to wait for - * @param timeout the maximum time to wait. If less than - * or equal to zero, do not wait at all. - * @throws InterruptedException if interrupted while waiting. - * @see Thread#join(long, int) - */ - public void timedJoin(Thread thread, long timeout) - throws InterruptedException { - if (timeout > 0) { - long ms = toMillis(timeout); - int ns = excessNanos(timeout, ms); - thread.join(ms, ns); - } - } - - /** - * Performs a <tt>Thread.sleep</tt> using this unit. - * This is a convenience method that converts time arguments into the - * form required by the <tt>Thread.sleep</tt> method. - * @param timeout the minimum time to sleep. If less than - * or equal to zero, do not sleep at all. - * @throws InterruptedException if interrupted while sleeping. - * @see Thread#sleep - */ - public void sleep(long timeout) throws InterruptedException { - if (timeout > 0) { - long ms = toMillis(timeout); - int ns = excessNanos(timeout, ms); - Thread.sleep(ms, ns); - } - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/TimeoutException.java b/libjava/classpath/external/jsr166/java/util/concurrent/TimeoutException.java deleted file mode 100644 index 8b84f28..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/TimeoutException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent; - -/** - * Exception thrown when a blocking operation times out. Blocking - * operations for which a timeout is specified need a means to - * indicate that the timeout has occurred. For many such operations it - * is possible to return a value that indicates timeout; when that is - * not possible or desirable then <tt>TimeoutException</tt> should be - * declared and thrown. - * - * @since 1.5 - * @author Doug Lea - */ -public class TimeoutException extends Exception { - private static final long serialVersionUID = 1900926677490660714L; - - /** - * Constructs a <tt>TimeoutException</tt> with no specified detail - * message. - */ - public TimeoutException() {} - - /** - * Constructs a <tt>TimeoutException</tt> with the specified detail - * message. - * - * @param message the detail message - */ - public TimeoutException(String message) { - super(message); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java deleted file mode 100644 index bd823bd..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; - -/** - * A <tt>boolean</tt> value that may be updated atomically. See the - * {@link java.util.concurrent.atomic} package specification for - * description of the properties of atomic variables. An - * <tt>AtomicBoolean</tt> is used in applications such as atomically - * updated flags, and cannot be used as a replacement for a - * {@link java.lang.Boolean}. - * - * @since 1.5 - * @author Doug Lea - */ -public class AtomicBoolean implements java.io.Serializable { - private static final long serialVersionUID = 4654671469794556979L; - // setup to use Unsafe.compareAndSwapInt for updates - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; - - static { - try { - valueOffset = unsafe.objectFieldOffset - (AtomicBoolean.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } - } - - private volatile int value; - - /** - * Creates a new <tt>AtomicBoolean</tt> with the given initial value. - * - * @param initialValue the initial value - */ - public AtomicBoolean(boolean initialValue) { - value = initialValue ? 1 : 0; - } - - /** - * Creates a new <tt>AtomicBoolean</tt> with initial value <tt>false</tt>. - */ - public AtomicBoolean() { - } - - /** - * Returns the current value. - * - * @return the current value - */ - public final boolean get() { - return value != 0; - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that - * the actual value was not equal to the expected value. - */ - public final boolean compareAndSet(boolean expect, boolean update) { - int e = expect ? 1 : 0; - int u = update ? 1 : 0; - return unsafe.compareAndSwapInt(this, valueOffset, e, u); - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public boolean weakCompareAndSet(boolean expect, boolean update) { - int e = expect ? 1 : 0; - int u = update ? 1 : 0; - return unsafe.compareAndSwapInt(this, valueOffset, e, u); - } - - /** - * Unconditionally sets to the given value. - * - * @param newValue the new value - */ - public final void set(boolean newValue) { - value = newValue ? 1 : 0; - } - - /** - * Eventually sets to the given value. - * - * @param newValue the new value - * @since 1.6 - */ - public final void lazySet(boolean newValue) { - int v = newValue ? 1 : 0; - unsafe.putOrderedInt(this, valueOffset, v); - } - - /** - * Atomically sets to the given value and returns the previous value. - * - * @param newValue the new value - * @return the previous value - */ - public final boolean getAndSet(boolean newValue) { - for (;;) { - boolean current = get(); - if (compareAndSet(current, newValue)) - return current; - } - } - - /** - * Returns the String representation of the current value. - * @return the String representation of the current value. - */ - public String toString() { - return Boolean.toString(get()); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java deleted file mode 100644 index 0f723f6..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; - -/** - * An <tt>int</tt> value that may be updated atomically. See the - * {@link java.util.concurrent.atomic} package specification for - * description of the properties of atomic variables. An - * <tt>AtomicInteger</tt> is used in applications such as atomically - * incremented counters, and cannot be used as a replacement for an - * {@link java.lang.Integer}. However, this class does extend - * <tt>Number</tt> to allow uniform access by tools and utilities that - * deal with numerically-based classes. - * - * @since 1.5 - * @author Doug Lea -*/ -public class AtomicInteger extends Number implements java.io.Serializable { - private static final long serialVersionUID = 6214790243416807050L; - - // setup to use Unsafe.compareAndSwapInt for updates - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; - - static { - try { - valueOffset = unsafe.objectFieldOffset - (AtomicInteger.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } - } - - private volatile int value; - - /** - * Creates a new AtomicInteger with the given initial value. - * - * @param initialValue the initial value - */ - public AtomicInteger(int initialValue) { - value = initialValue; - } - - /** - * Creates a new AtomicInteger with initial value <tt>0</tt>. - */ - public AtomicInteger() { - } - - /** - * Gets the current value. - * - * @return the current value - */ - public final int get() { - return value; - } - - /** - * Sets to the given value. - * - * @param newValue the new value - */ - public final void set(int newValue) { - value = newValue; - } - - /** - * Eventually sets to the given value. - * - * @param newValue the new value - * @since 1.6 - */ - public final void lazySet(int newValue) { - unsafe.putOrderedInt(this, valueOffset, newValue); - } - - /** - * Atomically sets to the given value and returns the old value. - * - * @param newValue the new value - * @return the previous value - */ - public final int getAndSet(int newValue) { - for (;;) { - int current = get(); - if (compareAndSet(current, newValue)) - return current; - } - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that - * the actual value was not equal to the expected value. - */ - public final boolean compareAndSet(int expect, int update) { - return unsafe.compareAndSwapInt(this, valueOffset, expect, update); - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public final boolean weakCompareAndSet(int expect, int update) { - return unsafe.compareAndSwapInt(this, valueOffset, expect, update); - } - - /** - * Atomically increments by one the current value. - * - * @return the previous value - */ - public final int getAndIncrement() { - for (;;) { - int current = get(); - int next = current + 1; - if (compareAndSet(current, next)) - return current; - } - } - - /** - * Atomically decrements by one the current value. - * - * @return the previous value - */ - public final int getAndDecrement() { - for (;;) { - int current = get(); - int next = current - 1; - if (compareAndSet(current, next)) - return current; - } - } - - /** - * Atomically adds the given value to the current value. - * - * @param delta the value to add - * @return the previous value - */ - public final int getAndAdd(int delta) { - for (;;) { - int current = get(); - int next = current + delta; - if (compareAndSet(current, next)) - return current; - } - } - - /** - * Atomically increments by one the current value. - * - * @return the updated value - */ - public final int incrementAndGet() { - for (;;) { - int current = get(); - int next = current + 1; - if (compareAndSet(current, next)) - return next; - } - } - - /** - * Atomically decrements by one the current value. - * - * @return the updated value - */ - public final int decrementAndGet() { - for (;;) { - int current = get(); - int next = current - 1; - if (compareAndSet(current, next)) - return next; - } - } - - /** - * Atomically adds the given value to the current value. - * - * @param delta the value to add - * @return the updated value - */ - public final int addAndGet(int delta) { - for (;;) { - int current = get(); - int next = current + delta; - if (compareAndSet(current, next)) - return next; - } - } - - /** - * Returns the String representation of the current value. - * @return the String representation of the current value. - */ - public String toString() { - return Integer.toString(get()); - } - - - public int intValue() { - return get(); - } - - public long longValue() { - return (long)get(); - } - - public float floatValue() { - return (float)get(); - } - - public double doubleValue() { - return (double)get(); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java deleted file mode 100644 index 2ad754f..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; -import java.util.*; - -/** - * An <tt>int</tt> array in which elements may be updated atomically. - * See the {@link java.util.concurrent.atomic} package - * specification for description of the properties of atomic - * variables. - * @since 1.5 - * @author Doug Lea - */ -public class AtomicIntegerArray implements java.io.Serializable { - private static final long serialVersionUID = 2862133569453604235L; - - // setup to use Unsafe.compareAndSwapInt for updates - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final int base = unsafe.arrayBaseOffset(int[].class); - private static final int scale = unsafe.arrayIndexScale(int[].class); - private final int[] array; - - private long rawIndex(int i) { - if (i < 0 || i >= array.length) - throw new IndexOutOfBoundsException("index " + i); - return base + i * scale; - } - - /** - * Creates a new AtomicIntegerArray of given length. - * - * @param length the length of the array - */ - public AtomicIntegerArray(int length) { - array = new int[length]; - // must perform at least one volatile write to conform to JMM - if (length > 0) - unsafe.putIntVolatile(array, rawIndex(0), 0); - } - - /** - * Creates a new AtomicIntegerArray with the same length as, and - * all elements copied from, the given array. - * - * @param array the array to copy elements from - * @throws NullPointerException if array is null - */ - public AtomicIntegerArray(int[] array) { - if (array == null) - throw new NullPointerException(); - int length = array.length; - this.array = new int[length]; - if (length > 0) { - int last = length-1; - for (int i = 0; i < last; ++i) - this.array[i] = array[i]; - // Do the last write as volatile - unsafe.putIntVolatile(this.array, rawIndex(last), array[last]); - } - } - - /** - * Returns the length of the array. - * - * @return the length of the array - */ - public final int length() { - return array.length; - } - - /** - * Gets the current value at position <tt>i</tt>. - * - * @param i the index - * @return the current value - */ - public final int get(int i) { - return unsafe.getIntVolatile(array, rawIndex(i)); - } - - /** - * Sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - */ - public final void set(int i, int newValue) { - unsafe.putIntVolatile(array, rawIndex(i), newValue); - } - - /** - * Eventually sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - * @since 1.6 - */ - public final void lazySet(int i, int newValue) { - unsafe.putOrderedInt(array, rawIndex(i), newValue); - } - - /** - * Atomically sets the element at position <tt>i</tt> to the given - * value and returns the old value. - * - * @param i the index - * @param newValue the new value - * @return the previous value - */ - public final int getAndSet(int i, int newValue) { - while (true) { - int current = get(i); - if (compareAndSet(i, current, newValue)) - return current; - } - } - - /** - * Atomically sets the element at position <tt>i</tt> to the given - * updated value if the current value <tt>==</tt> the expected value. - * - * @param i the index - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that - * the actual value was not equal to the expected value. - */ - public final boolean compareAndSet(int i, int expect, int update) { - return unsafe.compareAndSwapInt(array, rawIndex(i), - expect, update); - } - - /** - * Atomically sets the element at position <tt>i</tt> to the given - * updated value if the current value <tt>==</tt> the expected value. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param i the index - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public final boolean weakCompareAndSet(int i, int expect, int update) { - return compareAndSet(i, expect, update); - } - - /** - * Atomically increments by one the element at index <tt>i</tt>. - * - * @param i the index - * @return the previous value - */ - public final int getAndIncrement(int i) { - while (true) { - int current = get(i); - int next = current + 1; - if (compareAndSet(i, current, next)) - return current; - } - } - - /** - * Atomically decrements by one the element at index <tt>i</tt>. - * - * @param i the index - * @return the previous value - */ - public final int getAndDecrement(int i) { - while (true) { - int current = get(i); - int next = current - 1; - if (compareAndSet(i, current, next)) - return current; - } - } - - /** - * Atomically adds the given value to the element at index <tt>i</tt>. - * - * @param i the index - * @param delta the value to add - * @return the previous value - */ - public final int getAndAdd(int i, int delta) { - while (true) { - int current = get(i); - int next = current + delta; - if (compareAndSet(i, current, next)) - return current; - } - } - - /** - * Atomically increments by one the element at index <tt>i</tt>. - * - * @param i the index - * @return the updated value - */ - public final int incrementAndGet(int i) { - while (true) { - int current = get(i); - int next = current + 1; - if (compareAndSet(i, current, next)) - return next; - } - } - - /** - * Atomically decrements by one the element at index <tt>i</tt>. - * - * @param i the index - * @return the updated value - */ - public final int decrementAndGet(int i) { - while (true) { - int current = get(i); - int next = current - 1; - if (compareAndSet(i, current, next)) - return next; - } - } - - /** - * Atomically adds the given value to the element at index <tt>i</tt>. - * - * @param i the index - * @param delta the value to add - * @return the updated value - */ - public final int addAndGet(int i, int delta) { - while (true) { - int current = get(i); - int next = current + delta; - if (compareAndSet(i, current, next)) - return next; - } - } - - /** - * Returns the String representation of the current values of array. - * @return the String representation of the current values of array. - */ - public String toString() { - if (array.length > 0) // force volatile read - get(0); - return Arrays.toString(array); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java deleted file mode 100644 index c957bbf..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; -import java.lang.reflect.*; - -/** - * A reflection-based utility that enables atomic updates to - * designated <tt>volatile int</tt> fields of designated classes. - * This class is designed for use in atomic data structures in which - * several fields of the same node are independently subject to atomic - * updates. - * - * <p>Note that the guarantees of the {@code compareAndSet} - * method in this class are weaker than in other atomic classes. - * Because this class cannot ensure that all uses of the field - * are appropriate for purposes of atomic access, it can - * guarantee atomicity only with respect to other invocations of - * {@code compareAndSet} and {@code set} on the same updater. - * - * @since 1.5 - * @author Doug Lea - * @param <T> The type of the object holding the updatable field - */ -public abstract class AtomicIntegerFieldUpdater<T> { - /** - * Creates and returns an updater for objects with the given field. - * The Class argument is needed to check that reflective types and - * generic types match. - * - * @param tclass the class of the objects holding the field - * @param fieldName the name of the field to be updated - * @return the updater - * @throws IllegalArgumentException if the field is not a - * volatile integer type - * @throws RuntimeException with a nested reflection-based - * exception if the class does not hold field or is the wrong type - */ - public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { - return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName); - } - - /** - * Protected do-nothing constructor for use by subclasses. - */ - protected AtomicIntegerFieldUpdater() { - } - - /** - * Atomically sets the field of the given object managed by this updater - * to the given updated value if the current value <tt>==</tt> the - * expected value. This method is guaranteed to be atomic with respect to - * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not - * necessarily with respect to other changes in the field. - * - * @param obj An object whose field to conditionally set - * @param expect the expected value - * @param update the new value - * @return true if successful - * @throws ClassCastException if <tt>obj</tt> is not an instance - * of the class possessing the field established in the constructor - */ - public abstract boolean compareAndSet(T obj, int expect, int update); - - /** - * Atomically sets the field of the given object managed by this updater - * to the given updated value if the current value <tt>==</tt> the - * expected value. This method is guaranteed to be atomic with respect to - * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not - * necessarily with respect to other changes in the field. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param obj An object whose field to conditionally set - * @param expect the expected value - * @param update the new value - * @return true if successful - * @throws ClassCastException if <tt>obj</tt> is not an instance - * of the class possessing the field established in the constructor - */ - public abstract boolean weakCompareAndSet(T obj, int expect, int update); - - /** - * Sets the field of the given object managed by this updater to the - * given updated value. This operation is guaranteed to act as a volatile - * store with respect to subsequent invocations of - * <tt>compareAndSet</tt>. - * - * @param obj An object whose field to set - * @param newValue the new value - */ - public abstract void set(T obj, int newValue); - - /** - * Eventually sets the field of the given object managed by this - * updater to the given updated value. - * - * @param obj An object whose field to set - * @param newValue the new value - * @since 1.6 - */ - public abstract void lazySet(T obj, int newValue); - - - /** - * Gets the current value held in the field of the given object managed - * by this updater. - * - * @param obj An object whose field to get - * @return the current value - */ - public abstract int get(T obj); - - /** - * Atomically sets the field of the given object managed by this updater - * to the given value and returns the old value. - * - * @param obj An object whose field to get and set - * @param newValue the new value - * @return the previous value - */ - public int getAndSet(T obj, int newValue) { - for (;;) { - int current = get(obj); - if (compareAndSet(obj, current, newValue)) - return current; - } - } - - /** - * Atomically increments by one the current value of the field of the - * given object managed by this updater. - * - * @param obj An object whose field to get and set - * @return the previous value - */ - public int getAndIncrement(T obj) { - for (;;) { - int current = get(obj); - int next = current + 1; - if (compareAndSet(obj, current, next)) - return current; - } - } - - /** - * Atomically decrements by one the current value of the field of the - * given object managed by this updater. - * - * @param obj An object whose field to get and set - * @return the previous value - */ - public int getAndDecrement(T obj) { - for (;;) { - int current = get(obj); - int next = current - 1; - if (compareAndSet(obj, current, next)) - return current; - } - } - - /** - * Atomically adds the given value to the current value of the field of - * the given object managed by this updater. - * - * @param obj An object whose field to get and set - * @param delta the value to add - * @return the previous value - */ - public int getAndAdd(T obj, int delta) { - for (;;) { - int current = get(obj); - int next = current + delta; - if (compareAndSet(obj, current, next)) - return current; - } - } - - /** - * Atomically increments by one the current value of the field of the - * given object managed by this updater. - * - * @param obj An object whose field to get and set - * @return the updated value - */ - public int incrementAndGet(T obj) { - for (;;) { - int current = get(obj); - int next = current + 1; - if (compareAndSet(obj, current, next)) - return next; - } - } - - /** - * Atomically decrements by one the current value of the field of the - * given object managed by this updater. - * - * @param obj An object whose field to get and set - * @return the updated value - */ - public int decrementAndGet(T obj) { - for (;;) { - int current = get(obj); - int next = current - 1; - if (compareAndSet(obj, current, next)) - return next; - } - } - - /** - * Atomically adds the given value to the current value of the field of - * the given object managed by this updater. - * - * @param obj An object whose field to get and set - * @param delta the value to add - * @return the updated value - */ - public int addAndGet(T obj, int delta) { - for (;;) { - int current = get(obj); - int next = current + delta; - if (compareAndSet(obj, current, next)) - return next; - } - } - - /** - * Standard hotspot implementation using intrinsics - */ - private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> { - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private final long offset; - private final Class<T> tclass; - private final Class cclass; - - AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) { - Field field = null; - Class caller = null; - int modifiers = 0; - try { - field = tclass.getDeclaredField(fieldName); - caller = sun.reflect.Reflection.getCallerClass(3); - modifiers = field.getModifiers(); - sun.reflect.misc.ReflectUtil.ensureMemberAccess( - caller, tclass, null, modifiers); - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); - } catch(Exception ex) { - throw new RuntimeException(ex); - } - - Class fieldt = field.getType(); - if (fieldt != int.class) - throw new IllegalArgumentException("Must be integer type"); - - if (!Modifier.isVolatile(modifiers)) - throw new IllegalArgumentException("Must be volatile type"); - - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; - this.tclass = tclass; - offset = unsafe.objectFieldOffset(field); - } - - private void fullCheck(T obj) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); - } - - public boolean compareAndSet(T obj, int expect, int update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapInt(obj, offset, expect, update); - } - - public boolean weakCompareAndSet(T obj, int expect, int update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapInt(obj, offset, expect, update); - } - - public void set(T obj, int newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putIntVolatile(obj, offset, newValue); - } - - public void lazySet(T obj, int newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putOrderedInt(obj, offset, newValue); - } - - public final int get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getIntVolatile(obj, offset); - } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java deleted file mode 100644 index fa254ba..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; - -/** - * A <tt>long</tt> value that may be updated atomically. See the - * {@link java.util.concurrent.atomic} package specification for - * description of the properties of atomic variables. An - * <tt>AtomicLong</tt> is used in applications such as atomically - * incremented sequence numbers, and cannot be used as a replacement - * for a {@link java.lang.Long}. However, this class does extend - * <tt>Number</tt> to allow uniform access by tools and utilities that - * deal with numerically-based classes. - * - * @since 1.5 - * @author Doug Lea - */ -public class AtomicLong extends Number implements java.io.Serializable { - private static final long serialVersionUID = 1927816293512124184L; - - // setup to use Unsafe.compareAndSwapLong for updates - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; - - /** - * Records whether the underlying JVM supports lockless - * CompareAndSet for longs. While the unsafe.CompareAndSetLong - * method works in either case, some constructions should be - * handled at Java level to avoid locking user-visible locks. - */ - static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8(); - - /** - * Returns whether underlying JVM supports lockless CompareAndSet - * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS. - */ - private static native boolean VMSupportsCS8(); - - static { - try { - valueOffset = unsafe.objectFieldOffset - (AtomicLong.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } - } - - private volatile long value; - - /** - * Creates a new AtomicLong with the given initial value. - * - * @param initialValue the initial value - */ - public AtomicLong(long initialValue) { - value = initialValue; - } - - /** - * Creates a new AtomicLong with initial value <tt>0</tt>. - */ - public AtomicLong() { - } - - /** - * Gets the current value. - * - * @return the current value - */ - public final long get() { - return value; - } - - /** - * Sets to the given value. - * - * @param newValue the new value - */ - public final void set(long newValue) { - value = newValue; - } - - /** - * Eventually sets to the given value. - * - * @param newValue the new value - * @since 1.6 - */ - public final void lazySet(long newValue) { - unsafe.putOrderedLong(this, valueOffset, newValue); - } - - /** - * Atomically sets to the given value and returns the old value. - * - * @param newValue the new value - * @return the previous value - */ - public final long getAndSet(long newValue) { - while (true) { - long current = get(); - if (compareAndSet(current, newValue)) - return current; - } - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that - * the actual value was not equal to the expected value. - */ - public final boolean compareAndSet(long expect, long update) { - return unsafe.compareAndSwapLong(this, valueOffset, expect, update); - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public final boolean weakCompareAndSet(long expect, long update) { - return unsafe.compareAndSwapLong(this, valueOffset, expect, update); - } - - /** - * Atomically increments by one the current value. - * - * @return the previous value - */ - public final long getAndIncrement() { - while (true) { - long current = get(); - long next = current + 1; - if (compareAndSet(current, next)) - return current; - } - } - - /** - * Atomically decrements by one the current value. - * - * @return the previous value - */ - public final long getAndDecrement() { - while (true) { - long current = get(); - long next = current - 1; - if (compareAndSet(current, next)) - return current; - } - } - - /** - * Atomically adds the given value to the current value. - * - * @param delta the value to add - * @return the previous value - */ - public final long getAndAdd(long delta) { - while (true) { - long current = get(); - long next = current + delta; - if (compareAndSet(current, next)) - return current; - } - } - - /** - * Atomically increments by one the current value. - * - * @return the updated value - */ - public final long incrementAndGet() { - for (;;) { - long current = get(); - long next = current + 1; - if (compareAndSet(current, next)) - return next; - } - } - - /** - * Atomically decrements by one the current value. - * - * @return the updated value - */ - public final long decrementAndGet() { - for (;;) { - long current = get(); - long next = current - 1; - if (compareAndSet(current, next)) - return next; - } - } - - /** - * Atomically adds the given value to the current value. - * - * @param delta the value to add - * @return the updated value - */ - public final long addAndGet(long delta) { - for (;;) { - long current = get(); - long next = current + delta; - if (compareAndSet(current, next)) - return next; - } - } - - /** - * Returns the String representation of the current value. - * @return the String representation of the current value. - */ - public String toString() { - return Long.toString(get()); - } - - - public int intValue() { - return (int)get(); - } - - public long longValue() { - return (long)get(); - } - - public float floatValue() { - return (float)get(); - } - - public double doubleValue() { - return (double)get(); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java deleted file mode 100644 index c582cba..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; -import java.util.*; - -/** - * A <tt>long</tt> array in which elements may be updated atomically. - * See the {@link java.util.concurrent.atomic} package specification - * for description of the properties of atomic variables. - * @since 1.5 - * @author Doug Lea - */ -public class AtomicLongArray implements java.io.Serializable { - private static final long serialVersionUID = -2308431214976778248L; - - // setup to use Unsafe.compareAndSwapInt for updates - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final int base = unsafe.arrayBaseOffset(long[].class); - private static final int scale = unsafe.arrayIndexScale(long[].class); - private final long[] array; - - private long rawIndex(int i) { - if (i < 0 || i >= array.length) - throw new IndexOutOfBoundsException("index " + i); - return base + i * scale; - } - - /** - * Creates a new AtomicLongArray of given length. - * - * @param length the length of the array - */ - public AtomicLongArray(int length) { - array = new long[length]; - // must perform at least one volatile write to conform to JMM - if (length > 0) - unsafe.putLongVolatile(array, rawIndex(0), 0); - } - - /** - * Creates a new AtomicLongArray with the same length as, and - * all elements copied from, the given array. - * - * @param array the array to copy elements from - * @throws NullPointerException if array is null - */ - public AtomicLongArray(long[] array) { - if (array == null) - throw new NullPointerException(); - int length = array.length; - this.array = new long[length]; - if (length > 0) { - int last = length-1; - for (int i = 0; i < last; ++i) - this.array[i] = array[i]; - // Do the last write as volatile - unsafe.putLongVolatile(this.array, rawIndex(last), array[last]); - } - } - - /** - * Returns the length of the array. - * - * @return the length of the array - */ - public final int length() { - return array.length; - } - - /** - * Gets the current value at position <tt>i</tt>. - * - * @param i the index - * @return the current value - */ - public final long get(int i) { - return unsafe.getLongVolatile(array, rawIndex(i)); - } - - /** - * Sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - */ - public final void set(int i, long newValue) { - unsafe.putLongVolatile(array, rawIndex(i), newValue); - } - - /** - * Eventually sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - * @since 1.6 - */ - public final void lazySet(int i, long newValue) { - unsafe.putOrderedLong(array, rawIndex(i), newValue); - } - - - /** - * Atomically sets the element at position <tt>i</tt> to the given value - * and returns the old value. - * - * @param i the index - * @param newValue the new value - * @return the previous value - */ - public final long getAndSet(int i, long newValue) { - while (true) { - long current = get(i); - if (compareAndSet(i, current, newValue)) - return current; - } - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * - * @param i the index - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that - * the actual value was not equal to the expected value. - */ - public final boolean compareAndSet(int i, long expect, long update) { - return unsafe.compareAndSwapLong(array, rawIndex(i), - expect, update); - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param i the index - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public final boolean weakCompareAndSet(int i, long expect, long update) { - return compareAndSet(i, expect, update); - } - - /** - * Atomically increments by one the element at index <tt>i</tt>. - * - * @param i the index - * @return the previous value - */ - public final long getAndIncrement(int i) { - while (true) { - long current = get(i); - long next = current + 1; - if (compareAndSet(i, current, next)) - return current; - } - } - - /** - * Atomically decrements by one the element at index <tt>i</tt>. - * - * @param i the index - * @return the previous value - */ - public final long getAndDecrement(int i) { - while (true) { - long current = get(i); - long next = current - 1; - if (compareAndSet(i, current, next)) - return current; - } - } - - /** - * Atomically adds the given value to the element at index <tt>i</tt>. - * - * @param i the index - * @param delta the value to add - * @return the previous value - */ - public final long getAndAdd(int i, long delta) { - while (true) { - long current = get(i); - long next = current + delta; - if (compareAndSet(i, current, next)) - return current; - } - } - - /** - * Atomically increments by one the element at index <tt>i</tt>. - * - * @param i the index - * @return the updated value - */ - public final long incrementAndGet(int i) { - while (true) { - long current = get(i); - long next = current + 1; - if (compareAndSet(i, current, next)) - return next; - } - } - - /** - * Atomically decrements by one the element at index <tt>i</tt>. - * - * @param i the index - * @return the updated value - */ - public final long decrementAndGet(int i) { - while (true) { - long current = get(i); - long next = current - 1; - if (compareAndSet(i, current, next)) - return next; - } - } - - /** - * Atomically adds the given value to the element at index <tt>i</tt>. - * - * @param i the index - * @param delta the value to add - * @return the updated value - */ - public long addAndGet(int i, long delta) { - while (true) { - long current = get(i); - long next = current + delta; - if (compareAndSet(i, current, next)) - return next; - } - } - - /** - * Returns the String representation of the current values of array. - * @return the String representation of the current values of array. - */ - public String toString() { - if (array.length > 0) // force volatile read - get(0); - return Arrays.toString(array); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java deleted file mode 100644 index f6135d1..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; -import java.lang.reflect.*; - -/** - * A reflection-based utility that enables atomic updates to - * designated <tt>volatile long</tt> fields of designated classes. - * This class is designed for use in atomic data structures in which - * several fields of the same node are independently subject to atomic - * updates. - * - * <p>Note that the guarantees of the {@code compareAndSet} - * method in this class are weaker than in other atomic classes. - * Because this class cannot ensure that all uses of the field - * are appropriate for purposes of atomic access, it can - * guarantee atomicity only with respect to other invocations of - * {@code compareAndSet} and {@code set} on the same updater. - * - * @since 1.5 - * @author Doug Lea - * @param <T> The type of the object holding the updatable field - */ -public abstract class AtomicLongFieldUpdater<T> { - /** - * Creates and returns an updater for objects with the given field. - * The Class argument is needed to check that reflective types and - * generic types match. - * - * @param tclass the class of the objects holding the field - * @param fieldName the name of the field to be updated. - * @return the updater - * @throws IllegalArgumentException if the field is not a - * volatile long type. - * @throws RuntimeException with a nested reflection-based - * exception if the class does not hold field or is the wrong type. - */ - public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { - if (AtomicLong.VM_SUPPORTS_LONG_CAS) - return new CASUpdater<U>(tclass, fieldName); - else - return new LockedUpdater<U>(tclass, fieldName); - } - - /** - * Protected do-nothing constructor for use by subclasses. - */ - protected AtomicLongFieldUpdater() { - } - - /** - * Atomically sets the field of the given object managed by this updater - * to the given updated value if the current value <tt>==</tt> the - * expected value. This method is guaranteed to be atomic with respect to - * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not - * necessarily with respect to other changes in the field. - * - * @param obj An object whose field to conditionally set - * @param expect the expected value - * @param update the new value - * @return true if successful. - * @throws ClassCastException if <tt>obj</tt> is not an instance - * of the class possessing the field established in the constructor. - */ - public abstract boolean compareAndSet(T obj, long expect, long update); - - /** - * Atomically sets the field of the given object managed by this updater - * to the given updated value if the current value <tt>==</tt> the - * expected value. This method is guaranteed to be atomic with respect to - * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not - * necessarily with respect to other changes in the field. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param obj An object whose field to conditionally set - * @param expect the expected value - * @param update the new value - * @return true if successful. - * @throws ClassCastException if <tt>obj</tt> is not an instance - * of the class possessing the field established in the constructor. - */ - public abstract boolean weakCompareAndSet(T obj, long expect, long update); - - /** - * Sets the field of the given object managed by this updater to the - * given updated value. This operation is guaranteed to act as a volatile - * store with respect to subsequent invocations of - * <tt>compareAndSet</tt>. - * - * @param obj An object whose field to set - * @param newValue the new value - */ - public abstract void set(T obj, long newValue); - - /** - * Eventually sets the field of the given object managed by this - * updater to the given updated value. - * - * @param obj An object whose field to set - * @param newValue the new value - * @since 1.6 - */ - public abstract void lazySet(T obj, long newValue); - - /** - * Gets the current value held in the field of the given object managed - * by this updater. - * - * @param obj An object whose field to get - * @return the current value - */ - public abstract long get(T obj); - - /** - * Atomically sets the field of the given object managed by this updater - * to the given value and returns the old value. - * - * @param obj An object whose field to get and set - * @param newValue the new value - * @return the previous value - */ - public long getAndSet(T obj, long newValue) { - for (;;) { - long current = get(obj); - if (compareAndSet(obj, current, newValue)) - return current; - } - } - - /** - * Atomically increments by one the current value of the field of the - * given object managed by this updater. - * - * @param obj An object whose field to get and set - * @return the previous value - */ - public long getAndIncrement(T obj) { - for (;;) { - long current = get(obj); - long next = current + 1; - if (compareAndSet(obj, current, next)) - return current; - } - } - - /** - * Atomically decrements by one the current value of the field of the - * given object managed by this updater. - * - * @param obj An object whose field to get and set - * @return the previous value - */ - public long getAndDecrement(T obj) { - for (;;) { - long current = get(obj); - long next = current - 1; - if (compareAndSet(obj, current, next)) - return current; - } - } - - /** - * Atomically adds the given value to the current value of the field of - * the given object managed by this updater. - * - * @param obj An object whose field to get and set - * @param delta the value to add - * @return the previous value - */ - public long getAndAdd(T obj, long delta) { - for (;;) { - long current = get(obj); - long next = current + delta; - if (compareAndSet(obj, current, next)) - return current; - } - } - - /** - * Atomically increments by one the current value of the field of the - * given object managed by this updater. - * - * @param obj An object whose field to get and set - * @return the updated value - */ - public long incrementAndGet(T obj) { - for (;;) { - long current = get(obj); - long next = current + 1; - if (compareAndSet(obj, current, next)) - return next; - } - } - - /** - * Atomically decrements by one the current value of the field of the - * given object managed by this updater. - * - * @param obj An object whose field to get and set - * @return the updated value - */ - public long decrementAndGet(T obj) { - for (;;) { - long current = get(obj); - long next = current - 1; - if (compareAndSet(obj, current, next)) - return next; - } - } - - /** - * Atomically adds the given value to the current value of the field of - * the given object managed by this updater. - * - * @param obj An object whose field to get and set - * @param delta the value to add - * @return the updated value - */ - public long addAndGet(T obj, long delta) { - for (;;) { - long current = get(obj); - long next = current + delta; - if (compareAndSet(obj, current, next)) - return next; - } - } - - private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> { - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private final long offset; - private final Class<T> tclass; - private final Class cclass; - - CASUpdater(Class<T> tclass, String fieldName) { - Field field = null; - Class caller = null; - int modifiers = 0; - try { - field = tclass.getDeclaredField(fieldName); - caller = sun.reflect.Reflection.getCallerClass(3); - modifiers = field.getModifiers(); - sun.reflect.misc.ReflectUtil.ensureMemberAccess( - caller, tclass, null, modifiers); - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); - } catch(Exception ex) { - throw new RuntimeException(ex); - } - - Class fieldt = field.getType(); - if (fieldt != long.class) - throw new IllegalArgumentException("Must be long type"); - - if (!Modifier.isVolatile(modifiers)) - throw new IllegalArgumentException("Must be volatile type"); - - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; - this.tclass = tclass; - offset = unsafe.objectFieldOffset(field); - } - - private void fullCheck(T obj) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); - } - - public boolean compareAndSet(T obj, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapLong(obj, offset, expect, update); - } - - public boolean weakCompareAndSet(T obj, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapLong(obj, offset, expect, update); - } - - public void set(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putLongVolatile(obj, offset, newValue); - } - - public void lazySet(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putOrderedLong(obj, offset, newValue); - } - - public long get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getLongVolatile(obj, offset); - } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException ( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } - } - - - private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> { - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private final long offset; - private final Class<T> tclass; - private final Class cclass; - - LockedUpdater(Class<T> tclass, String fieldName) { - Field field = null; - Class caller = null; - int modifiers = 0; - try { - field = tclass.getDeclaredField(fieldName); - caller = sun.reflect.Reflection.getCallerClass(3); - modifiers = field.getModifiers(); - sun.reflect.misc.ReflectUtil.ensureMemberAccess( - caller, tclass, null, modifiers); - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); - } catch(Exception ex) { - throw new RuntimeException(ex); - } - - Class fieldt = field.getType(); - if (fieldt != long.class) - throw new IllegalArgumentException("Must be long type"); - - if (!Modifier.isVolatile(modifiers)) - throw new IllegalArgumentException("Must be volatile type"); - - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; - this.tclass = tclass; - offset = unsafe.objectFieldOffset(field); - } - - private void fullCheck(T obj) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); - } - - public boolean compareAndSet(T obj, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - synchronized(this) { - long v = unsafe.getLong(obj, offset); - if (v != expect) - return false; - unsafe.putLong(obj, offset, update); - return true; - } - } - - public boolean weakCompareAndSet(T obj, long expect, long update) { - return compareAndSet(obj, expect, update); - } - - public void set(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - synchronized(this) { - unsafe.putLong(obj, offset, newValue); - } - } - - public void lazySet(T obj, long newValue) { - set(obj, newValue); - } - - public long get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - synchronized(this) { - return unsafe.getLong(obj, offset); - } - } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException ( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java deleted file mode 100644 index 85335b7..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; - -/** - * An <tt>AtomicMarkableReference</tt> maintains an object reference - * along with a mark bit, that can be updated atomically. - * <p> - * <p> Implementation note. This implementation maintains markable - * references by creating internal objects representing "boxed" - * [reference, boolean] pairs. - * - * @since 1.5 - * @author Doug Lea - * @param <V> The type of object referred to by this reference - */ -public class AtomicMarkableReference<V> { - - private static class ReferenceBooleanPair<T> { - private final T reference; - private final boolean bit; - ReferenceBooleanPair(T r, boolean i) { - reference = r; bit = i; - } - } - - private final AtomicReference<ReferenceBooleanPair<V>> atomicRef; - - /** - * Creates a new <tt>AtomicMarkableReference</tt> with the given - * initial values. - * - * @param initialRef the initial reference - * @param initialMark the initial mark - */ - public AtomicMarkableReference(V initialRef, boolean initialMark) { - atomicRef = new AtomicReference<ReferenceBooleanPair<V>> (new ReferenceBooleanPair<V>(initialRef, initialMark)); - } - - /** - * Returns the current value of the reference. - * - * @return the current value of the reference - */ - public V getReference() { - return atomicRef.get().reference; - } - - /** - * Returns the current value of the mark. - * - * @return the current value of the mark - */ - public boolean isMarked() { - return atomicRef.get().bit; - } - - /** - * Returns the current values of both the reference and the mark. - * Typical usage is <tt>boolean[1] holder; ref = v.get(holder); </tt>. - * - * @param markHolder an array of size of at least one. On return, - * <tt>markholder[0]</tt> will hold the value of the mark. - * @return the current value of the reference - */ - public V get(boolean[] markHolder) { - ReferenceBooleanPair<V> p = atomicRef.get(); - markHolder[0] = p.bit; - return p.reference; - } - - /** - * Atomically sets the value of both the reference and mark - * to the given update values if the - * current reference is <tt>==</tt> to the expected reference - * and the current mark is equal to the expected mark. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param expectedReference the expected value of the reference - * @param newReference the new value for the reference - * @param expectedMark the expected value of the mark - * @param newMark the new value for the mark - * @return true if successful - */ - public boolean weakCompareAndSet(V expectedReference, - V newReference, - boolean expectedMark, - boolean newMark) { - ReferenceBooleanPair<V> current = atomicRef.get(); - return expectedReference == current.reference && - expectedMark == current.bit && - ((newReference == current.reference && newMark == current.bit) || - atomicRef.weakCompareAndSet(current, - new ReferenceBooleanPair<V>(newReference, - newMark))); - } - - /** - * Atomically sets the value of both the reference and mark - * to the given update values if the - * current reference is <tt>==</tt> to the expected reference - * and the current mark is equal to the expected mark. - * - * @param expectedReference the expected value of the reference - * @param newReference the new value for the reference - * @param expectedMark the expected value of the mark - * @param newMark the new value for the mark - * @return true if successful - */ - public boolean compareAndSet(V expectedReference, - V newReference, - boolean expectedMark, - boolean newMark) { - ReferenceBooleanPair<V> current = atomicRef.get(); - return expectedReference == current.reference && - expectedMark == current.bit && - ((newReference == current.reference && newMark == current.bit) || - atomicRef.compareAndSet(current, - new ReferenceBooleanPair<V>(newReference, - newMark))); - } - - /** - * Unconditionally sets the value of both the reference and mark. - * - * @param newReference the new value for the reference - * @param newMark the new value for the mark - */ - public void set(V newReference, boolean newMark) { - ReferenceBooleanPair<V> current = atomicRef.get(); - if (newReference != current.reference || newMark != current.bit) - atomicRef.set(new ReferenceBooleanPair<V>(newReference, newMark)); - } - - /** - * Atomically sets the value of the mark to the given update value - * if the current reference is <tt>==</tt> to the expected - * reference. Any given invocation of this operation may fail - * (return <tt>false</tt>) spuriously, but repeated invocation - * when the current value holds the expected value and no other - * thread is also attempting to set the value will eventually - * succeed. - * - * @param expectedReference the expected value of the reference - * @param newMark the new value for the mark - * @return true if successful - */ - public boolean attemptMark(V expectedReference, boolean newMark) { - ReferenceBooleanPair<V> current = atomicRef.get(); - return expectedReference == current.reference && - (newMark == current.bit || - atomicRef.compareAndSet - (current, new ReferenceBooleanPair<V>(expectedReference, - newMark))); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java deleted file mode 100644 index e7c989c..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; - -/** - * An object reference that may be updated atomically. See the {@link - * java.util.concurrent.atomic} package specification for description - * of the properties of atomic variables. - * @since 1.5 - * @author Doug Lea - * @param <V> The type of object referred to by this reference - */ -public class AtomicReference<V> implements java.io.Serializable { - private static final long serialVersionUID = -1848883965231344442L; - - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; - - static { - try { - valueOffset = unsafe.objectFieldOffset - (AtomicReference.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } - } - - private volatile V value; - - /** - * Creates a new AtomicReference with the given initial value. - * - * @param initialValue the initial value - */ - public AtomicReference(V initialValue) { - value = initialValue; - } - - /** - * Creates a new AtomicReference with null initial value. - */ - public AtomicReference() { - } - - /** - * Gets the current value. - * - * @return the current value - */ - public final V get() { - return value; - } - - /** - * Sets to the given value. - * - * @param newValue the new value - */ - public final void set(V newValue) { - value = newValue; - } - - /** - * Eventually sets to the given value. - * - * @param newValue the new value - * @since 1.6 - */ - public final void lazySet(V newValue) { - unsafe.putOrderedObject(this, valueOffset, newValue); - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that - * the actual value was not equal to the expected value. - */ - public final boolean compareAndSet(V expect, V update) { - return unsafe.compareAndSwapObject(this, valueOffset, expect, update); - } - - /** - * Atomically sets the value to the given updated value - * if the current value <tt>==</tt> the expected value. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public final boolean weakCompareAndSet(V expect, V update) { - return unsafe.compareAndSwapObject(this, valueOffset, expect, update); - } - - /** - * Atomically sets to the given value and returns the old value. - * - * @param newValue the new value - * @return the previous value - */ - public final V getAndSet(V newValue) { - while (true) { - V x = get(); - if (compareAndSet(x, newValue)) - return x; - } - } - - /** - * Returns the String representation of the current value. - * @return the String representation of the current value. - */ - public String toString() { - return String.valueOf(get()); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java deleted file mode 100644 index 91b601e..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; -import java.util.*; - -/** - * An array of object references in which elements may be updated - * atomically. See the {@link java.util.concurrent.atomic} package - * specification for description of the properties of atomic - * variables. - * @since 1.5 - * @author Doug Lea - * @param <E> The base class of elements held in this array - */ -public class AtomicReferenceArray<E> implements java.io.Serializable { - private static final long serialVersionUID = -6209656149925076980L; - - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final int base = unsafe.arrayBaseOffset(Object[].class); - private static final int scale = unsafe.arrayIndexScale(Object[].class); - private final Object[] array; - - private long rawIndex(int i) { - if (i < 0 || i >= array.length) - throw new IndexOutOfBoundsException("index " + i); - return base + i * scale; - } - - /** - * Creates a new AtomicReferenceArray of given length. - * @param length the length of the array - */ - public AtomicReferenceArray(int length) { - array = new Object[length]; - // must perform at least one volatile write to conform to JMM - if (length > 0) - unsafe.putObjectVolatile(array, rawIndex(0), null); - } - - /** - * Creates a new AtomicReferenceArray with the same length as, and - * all elements copied from, the given array. - * - * @param array the array to copy elements from - * @throws NullPointerException if array is null - */ - public AtomicReferenceArray(E[] array) { - if (array == null) - throw new NullPointerException(); - int length = array.length; - this.array = new Object[length]; - if (length > 0) { - int last = length-1; - for (int i = 0; i < last; ++i) - this.array[i] = array[i]; - // Do the last write as volatile - E e = array[last]; - unsafe.putObjectVolatile(this.array, rawIndex(last), e); - } - } - - /** - * Returns the length of the array. - * - * @return the length of the array - */ - public final int length() { - return array.length; - } - - /** - * Gets the current value at position <tt>i</tt>. - * - * @param i the index - * @return the current value - */ - public final E get(int i) { - return (E) unsafe.getObjectVolatile(array, rawIndex(i)); - } - - /** - * Sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - */ - public final void set(int i, E newValue) { - unsafe.putObjectVolatile(array, rawIndex(i), newValue); - } - - /** - * Eventually sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - * @since 1.6 - */ - public final void lazySet(int i, E newValue) { - unsafe.putOrderedObject(array, rawIndex(i), newValue); - } - - - /** - * Atomically sets the element at position <tt>i</tt> to the given - * value and returns the old value. - * - * @param i the index - * @param newValue the new value - * @return the previous value - */ - public final E getAndSet(int i, E newValue) { - while (true) { - E current = get(i); - if (compareAndSet(i, current, newValue)) - return current; - } - } - - /** - * Atomically sets the element at position <tt>i</tt> to the given - * updated value if the current value <tt>==</tt> the expected value. - * @param i the index - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that - * the actual value was not equal to the expected value. - */ - public final boolean compareAndSet(int i, E expect, E update) { - return unsafe.compareAndSwapObject(array, rawIndex(i), - expect, update); - } - - /** - * Atomically sets the element at position <tt>i</tt> to the given - * updated value if the current value <tt>==</tt> the expected value. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param i the index - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public final boolean weakCompareAndSet(int i, E expect, E update) { - return compareAndSet(i, expect, update); - } - - /** - * Returns the String representation of the current values of array. - * @return the String representation of the current values of array. - */ - public String toString() { - if (array.length > 0) // force volatile read - get(0); - return Arrays.toString(array); - } - -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java deleted file mode 100644 index 24014a9..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; -import sun.misc.Unsafe; -import java.lang.reflect.*; - -/** - * A reflection-based utility that enables atomic updates to - * designated <tt>volatile</tt> reference fields of designated - * classes. This class is designed for use in atomic data structures - * in which several reference fields of the same node are - * independently subject to atomic updates. For example, a tree node - * might be declared as - * - * <pre> - * class Node { - * private volatile Node left, right; - * - * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater = - * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left"); - * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater = - * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right"); - * - * Node getLeft() { return left; } - * boolean compareAndSetLeft(Node expect, Node update) { - * return leftUpdater.compareAndSet(this, expect, update); - * } - * // ... and so on - * } - * </pre> - * - * <p>Note that the guarantees of the {@code compareAndSet} - * method in this class are weaker than in other atomic classes. - * Because this class cannot ensure that all uses of the field - * are appropriate for purposes of atomic access, it can - * guarantee atomicity only with respect to other invocations of - * {@code compareAndSet} and {@code set} on the same updater. - * - * @since 1.5 - * @author Doug Lea - * @param <T> The type of the object holding the updatable field - * @param <V> The type of the field - */ -public abstract class AtomicReferenceFieldUpdater<T, V> { - - /** - * Creates and returns an updater for objects with the given field. - * The Class arguments are needed to check that reflective types and - * generic types match. - * - * @param tclass the class of the objects holding the field. - * @param vclass the class of the field - * @param fieldName the name of the field to be updated. - * @return the updater - * @throws IllegalArgumentException if the field is not a volatile reference type. - * @throws RuntimeException with a nested reflection-based - * exception if the class does not hold field or is the wrong type. - */ - public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) { - return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass, - vclass, - fieldName); - } - - /** - * Protected do-nothing constructor for use by subclasses. - */ - protected AtomicReferenceFieldUpdater() { - } - - /** - * Atomically sets the field of the given object managed by this updater - * to the given updated value if the current value <tt>==</tt> the - * expected value. This method is guaranteed to be atomic with respect to - * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not - * necessarily with respect to other changes in the field. - * - * @param obj An object whose field to conditionally set - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public abstract boolean compareAndSet(T obj, V expect, V update); - - /** - * Atomically sets the field of the given object managed by this updater - * to the given updated value if the current value <tt>==</tt> the - * expected value. This method is guaranteed to be atomic with respect to - * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not - * necessarily with respect to other changes in the field. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param obj An object whose field to conditionally set - * @param expect the expected value - * @param update the new value - * @return true if successful. - */ - public abstract boolean weakCompareAndSet(T obj, V expect, V update); - - /** - * Sets the field of the given object managed by this updater to the - * given updated value. This operation is guaranteed to act as a volatile - * store with respect to subsequent invocations of - * <tt>compareAndSet</tt>. - * - * @param obj An object whose field to set - * @param newValue the new value - */ - public abstract void set(T obj, V newValue); - - /** - * Eventually sets the field of the given object managed by this - * updater to the given updated value. - * - * @param obj An object whose field to set - * @param newValue the new value - * @since 1.6 - */ - public abstract void lazySet(T obj, V newValue); - - /** - * Gets the current value held in the field of the given object managed - * by this updater. - * - * @param obj An object whose field to get - * @return the current value - */ - public abstract V get(T obj); - - /** - * Atomically sets the field of the given object managed by this updater - * to the given value and returns the old value. - * - * @param obj An object whose field to get and set - * @param newValue the new value - * @return the previous value - */ - public V getAndSet(T obj, V newValue) { - for (;;) { - V current = get(obj); - if (compareAndSet(obj, current, newValue)) - return current; - } - } - - private static final class AtomicReferenceFieldUpdaterImpl<T,V> - extends AtomicReferenceFieldUpdater<T,V> { - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private final long offset; - private final Class<T> tclass; - private final Class<V> vclass; - private final Class cclass; - - /* - * Internal type checks within all update methods contain - * internal inlined optimizations checking for the common - * cases where the class is final (in which case a simple - * getClass comparison suffices) or is of type Object (in - * which case no check is needed because all objects are - * instances of Object). The Object case is handled simply by - * setting vclass to null in constructor. The targetCheck and - * updateCheck methods are invoked when these faster - * screenings fail. - */ - - AtomicReferenceFieldUpdaterImpl(Class<T> tclass, - Class<V> vclass, - String fieldName) { - Field field = null; - Class fieldClass = null; - Class caller = null; - int modifiers = 0; - try { - field = tclass.getDeclaredField(fieldName); - caller = sun.reflect.Reflection.getCallerClass(3); - modifiers = field.getModifiers(); - sun.reflect.misc.ReflectUtil.ensureMemberAccess( - caller, tclass, null, modifiers); - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); - fieldClass = field.getType(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - if (vclass != fieldClass) - throw new ClassCastException(); - - if (!Modifier.isVolatile(modifiers)) - throw new IllegalArgumentException("Must be volatile type"); - - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; - this.tclass = tclass; - if (vclass == Object.class) - this.vclass = null; - else - this.vclass = vclass; - offset = unsafe.objectFieldOffset(field); - } - - void targetCheck(T obj) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); - } - - void updateCheck(T obj, V update) { - if (!tclass.isInstance(obj) || - (update != null && vclass != null && !vclass.isInstance(update))) - throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); - } - - public boolean compareAndSet(T obj, V expect, V update) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (update != null && vclass != null && - vclass != update.getClass())) - updateCheck(obj, update); - return unsafe.compareAndSwapObject(obj, offset, expect, update); - } - - public boolean weakCompareAndSet(T obj, V expect, V update) { - // same implementation as strong form for now - if (obj == null || obj.getClass() != tclass || cclass != null || - (update != null && vclass != null && - vclass != update.getClass())) - updateCheck(obj, update); - return unsafe.compareAndSwapObject(obj, offset, expect, update); - } - - public void set(T obj, V newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (newValue != null && vclass != null && - vclass != newValue.getClass())) - updateCheck(obj, newValue); - unsafe.putObjectVolatile(obj, offset, newValue); - } - - public void lazySet(T obj, V newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (newValue != null && vclass != null && - vclass != newValue.getClass())) - updateCheck(obj, newValue); - unsafe.putOrderedObject(obj, offset, newValue); - } - - public V get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) - targetCheck(obj); - return (V)unsafe.getObjectVolatile(obj, offset); - } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException ( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java deleted file mode 100644 index 5588082..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.atomic; - -/** - * An <tt>AtomicStampedReference</tt> maintains an object reference - * along with an integer "stamp", that can be updated atomically. - * - * <p> Implementation note. This implementation maintains stamped - * references by creating internal objects representing "boxed" - * [reference, integer] pairs. - * - * @since 1.5 - * @author Doug Lea - * @param <V> The type of object referred to by this reference - */ -public class AtomicStampedReference<V> { - - private static class ReferenceIntegerPair<T> { - private final T reference; - private final int integer; - ReferenceIntegerPair(T r, int i) { - reference = r; integer = i; - } - } - - private final AtomicReference<ReferenceIntegerPair<V>> atomicRef; - - /** - * Creates a new <tt>AtomicStampedReference</tt> with the given - * initial values. - * - * @param initialRef the initial reference - * @param initialStamp the initial stamp - */ - public AtomicStampedReference(V initialRef, int initialStamp) { - atomicRef = new AtomicReference<ReferenceIntegerPair<V>> - (new ReferenceIntegerPair<V>(initialRef, initialStamp)); - } - - /** - * Returns the current value of the reference. - * - * @return the current value of the reference - */ - public V getReference() { - return atomicRef.get().reference; - } - - /** - * Returns the current value of the stamp. - * - * @return the current value of the stamp - */ - public int getStamp() { - return atomicRef.get().integer; - } - - /** - * Returns the current values of both the reference and the stamp. - * Typical usage is <tt>int[1] holder; ref = v.get(holder); </tt>. - * - * @param stampHolder an array of size of at least one. On return, - * <tt>stampholder[0]</tt> will hold the value of the stamp. - * @return the current value of the reference - */ - public V get(int[] stampHolder) { - ReferenceIntegerPair<V> p = atomicRef.get(); - stampHolder[0] = p.integer; - return p.reference; - } - - /** - * Atomically sets the value of both the reference and stamp - * to the given update values if the - * current reference is <tt>==</tt> to the expected reference - * and the current stamp is equal to the expected stamp. - * May fail spuriously and does not provide ordering guarantees, - * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. - * - * @param expectedReference the expected value of the reference - * @param newReference the new value for the reference - * @param expectedStamp the expected value of the stamp - * @param newStamp the new value for the stamp - * @return true if successful - */ - public boolean weakCompareAndSet(V expectedReference, - V newReference, - int expectedStamp, - int newStamp) { - ReferenceIntegerPair<V> current = atomicRef.get(); - return expectedReference == current.reference && - expectedStamp == current.integer && - ((newReference == current.reference && - newStamp == current.integer) || - atomicRef.weakCompareAndSet(current, - new ReferenceIntegerPair<V>(newReference, - newStamp))); - } - - /** - * Atomically sets the value of both the reference and stamp - * to the given update values if the - * current reference is <tt>==</tt> to the expected reference - * and the current stamp is equal to the expected stamp. - * - * @param expectedReference the expected value of the reference - * @param newReference the new value for the reference - * @param expectedStamp the expected value of the stamp - * @param newStamp the new value for the stamp - * @return true if successful - */ - public boolean compareAndSet(V expectedReference, - V newReference, - int expectedStamp, - int newStamp) { - ReferenceIntegerPair<V> current = atomicRef.get(); - return expectedReference == current.reference && - expectedStamp == current.integer && - ((newReference == current.reference && - newStamp == current.integer) || - atomicRef.compareAndSet(current, - new ReferenceIntegerPair<V>(newReference, - newStamp))); - } - - - /** - * Unconditionally sets the value of both the reference and stamp. - * - * @param newReference the new value for the reference - * @param newStamp the new value for the stamp - */ - public void set(V newReference, int newStamp) { - ReferenceIntegerPair<V> current = atomicRef.get(); - if (newReference != current.reference || newStamp != current.integer) - atomicRef.set(new ReferenceIntegerPair<V>(newReference, newStamp)); - } - - /** - * Atomically sets the value of the stamp to the given update value - * if the current reference is <tt>==</tt> to the expected - * reference. Any given invocation of this operation may fail - * (return <tt>false</tt>) spuriously, but repeated invocation - * when the current value holds the expected value and no other - * thread is also attempting to set the value will eventually - * succeed. - * - * @param expectedReference the expected value of the reference - * @param newStamp the new value for the stamp - * @return true if successful - */ - public boolean attemptStamp(V expectedReference, int newStamp) { - ReferenceIntegerPair<V> current = atomicRef.get(); - return expectedReference == current.reference && - (newStamp == current.integer || - atomicRef.compareAndSet(current, - new ReferenceIntegerPair<V>(expectedReference, - newStamp))); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java deleted file mode 100644 index f3780e5..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; - -/** - * A synchronizer that may be exclusively owned by a thread. This - * class provides a basis for creating locks and related synchronizers - * that may entail a notion of ownership. The - * <tt>AbstractOwnableSynchronizer</tt> class itself does not manage or - * use this information. However, subclasses and tools may use - * appropriately maintained values to help control and monitor access - * and provide diagnostics. - * - * @since 1.6 - * @author Doug Lea - */ -public abstract class AbstractOwnableSynchronizer - implements java.io.Serializable { - - /** Use serial ID even though all fields transient. */ - private static final long serialVersionUID = 3737899427754241961L; - - /** - * Empty constructor for use by subclasses. - */ - protected AbstractOwnableSynchronizer() { } - - /** - * The current owner of exclusive mode synchronization. - */ - private transient Thread exclusiveOwnerThread; - - /** - * Sets the thread that currently owns exclusive access. A - * <tt>null</tt> argument indicates that no thread owns access. - * This method does not otherwise impose any synchronization or - * <tt>volatile</tt> field accesses. - */ - protected final void setExclusiveOwnerThread(Thread t) { - exclusiveOwnerThread = t; - } - - /** - * Returns the thread last set by - * <tt>setExclusiveOwnerThread</tt>, or <tt>null</tt> if never - * set. This method does not otherwise impose any synchronization - * or <tt>volatile</tt> field accesses. - * @return the owner thread - */ - protected final Thread getExclusiveOwnerThread() { - return exclusiveOwnerThread; - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java deleted file mode 100644 index 45d744b..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ /dev/null @@ -1,1934 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import sun.misc.Unsafe; - -/** - * A version of {@link AbstractQueuedSynchronizer} in - * which synchronization state is maintained as a <tt>long</tt>. - * This class has exactly the same structure, properties, and methods - * as <tt>AbstractQueuedSynchronizer</tt> with the exception - * that all state-related parameters and results are defined - * as <tt>long</tt> rather than <tt>int</tt>. This class - * may be useful when creating synchronizers such as - * multilevel locks and barriers that require - * 64 bits of state. - * - * <p>See {@link AbstractQueuedSynchronizer} for usage - * notes and examples. - * - * @since 1.6 - * @author Doug Lea - */ -public abstract class AbstractQueuedLongSynchronizer - extends AbstractOwnableSynchronizer - implements java.io.Serializable { - - private static final long serialVersionUID = 7373984972572414692L; - - /* - To keep sources in sync, the remainder of this source file is - exactly cloned from AbstractQueuedSynchronizer, replacing class - name and changing ints related with sync state to longs. Please - keep it that way. - */ - - /** - * Creates a new <tt>AbstractQueuedLongSynchronizer</tt> instance - * with initial synchronization state of zero. - */ - protected AbstractQueuedLongSynchronizer() { } - - /** - * Wait queue node class. - * - * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and - * Hagersten) lock queue. CLH locks are normally used for - * spinlocks. We instead use them for blocking synchronizers, but - * use the same basic tactic of holding some of the control - * information about a thread in the predecessor of its node. A - * "status" field in each node keeps track of whether a thread - * should block. A node is signalled when its predecessor - * releases. Each node of the queue otherwise serves as a - * specific-notification-style monitor holding a single waiting - * thread. The status field does NOT control whether threads are - * granted locks etc though. A thread may try to acquire if it is - * first in the queue. But being first does not guarantee success; - * it only gives the right to contend. So the currently released - * contender thread may need to rewait. - * - * <p>To enqueue into a CLH lock, you atomically splice it in as new - * tail. To dequeue, you just set the head field. - * <pre> - * +------+ prev +-----+ +-----+ - * head | | <---- | | <---- | | tail - * +------+ +-----+ +-----+ - * </pre> - * - * <p>Insertion into a CLH queue requires only a single atomic - * operation on "tail", so there is a simple atomic point of - * demarcation from unqueued to queued. Similarly, dequeing - * involves only updating the "head". However, it takes a bit - * more work for nodes to determine who their successors are, - * in part to deal with possible cancellation due to timeouts - * and interrupts. - * - * <p>The "prev" links (not used in original CLH locks), are mainly - * needed to handle cancellation. If a node is cancelled, its - * successor is (normally) relinked to a non-cancelled - * predecessor. For explanation of similar mechanics in the case - * of spin locks, see the papers by Scott and Scherer at - * http://www.cs.rochester.edu/u/scott/synchronization/ - * - * <p>We also use "next" links to implement blocking mechanics. - * The thread id for each node is kept in its own node, so a - * predecessor signals the next node to wake up by traversing - * next link to determine which thread it is. Determination of - * successor must avoid races with newly queued nodes to set - * the "next" fields of their predecessors. This is solved - * when necessary by checking backwards from the atomically - * updated "tail" when a node's successor appears to be null. - * (Or, said differently, the next-links are an optimization - * so that we don't usually need a backward scan.) - * - * <p>Cancellation introduces some conservatism to the basic - * algorithms. Since we must poll for cancellation of other - * nodes, we can miss noticing whether a cancelled node is - * ahead or behind us. This is dealt with by always unparking - * successors upon cancellation, allowing them to stabilize on - * a new predecessor. - * - * <p>CLH queues need a dummy header node to get started. But - * we don't create them on construction, because it would be wasted - * effort if there is never contention. Instead, the node - * is constructed and head and tail pointers are set upon first - * contention. - * - * <p>Threads waiting on Conditions use the same nodes, but - * use an additional link. Conditions only need to link nodes - * in simple (non-concurrent) linked queues because they are - * only accessed when exclusively held. Upon await, a node is - * inserted into a condition queue. Upon signal, the node is - * transferred to the main queue. A special value of status - * field is used to mark which queue a node is on. - * - * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill - * Scherer and Michael Scott, along with members of JSR-166 - * expert group, for helpful ideas, discussions, and critiques - * on the design of this class. - */ - static final class Node { - /** waitStatus value to indicate thread has cancelled */ - static final int CANCELLED = 1; - /** waitStatus value to indicate successor's thread needs unparking */ - static final int SIGNAL = -1; - /** waitStatus value to indicate thread is waiting on condition */ - static final int CONDITION = -2; - /** Marker to indicate a node is waiting in shared mode */ - static final Node SHARED = new Node(); - /** Marker to indicate a node is waiting in exclusive mode */ - static final Node EXCLUSIVE = null; - - /** - * Status field, taking on only the values: - * SIGNAL: The successor of this node is (or will soon be) - * blocked (via park), so the current node must - * unpark its successor when it releases or - * cancels. To avoid races, acquire methods must - * first indicate they need a signal, - * then retry the atomic acquire, and then, - * on failure, block. - * CANCELLED: This node is cancelled due to timeout or interrupt. - * Nodes never leave this state. In particular, - * a thread with cancelled node never again blocks. - * CONDITION: This node is currently on a condition queue. - * It will not be used as a sync queue node until - * transferred. (Use of this value here - * has nothing to do with the other uses - * of the field, but simplifies mechanics.) - * 0: None of the above - * - * The values are arranged numerically to simplify use. - * Non-negative values mean that a node doesn't need to - * signal. So, most code doesn't need to check for particular - * values, just for sign. - * - * The field is initialized to 0 for normal sync nodes, and - * CONDITION for condition nodes. It is modified only using - * CAS. - */ - volatile int waitStatus; - - /** - * Link to predecessor node that current node/thread relies on - * for checking waitStatus. Assigned during enqueing, and nulled - * out (for sake of GC) only upon dequeuing. Also, upon - * cancellation of a predecessor, we short-circuit while - * finding a non-cancelled one, which will always exist - * because the head node is never cancelled: A node becomes - * head only as a result of successful acquire. A - * cancelled thread never succeeds in acquiring, and a thread only - * cancels itself, not any other node. - */ - volatile Node prev; - - /** - * Link to the successor node that the current node/thread - * unparks upon release. Assigned once during enqueuing, and - * nulled out (for sake of GC) when no longer needed. Upon - * cancellation, we cannot adjust this field, but can notice - * status and bypass the node if cancelled. The enq operation - * does not assign next field of a predecessor until after - * attachment, so seeing a null next field does not - * necessarily mean that node is at end of queue. However, if - * a next field appears to be null, we can scan prev's from - * the tail to double-check. - */ - volatile Node next; - - /** - * The thread that enqueued this node. Initialized on - * construction and nulled out after use. - */ - volatile Thread thread; - - /** - * Link to next node waiting on condition, or the special - * value SHARED. Because condition queues are accessed only - * when holding in exclusive mode, we just need a simple - * linked queue to hold nodes while they are waiting on - * conditions. They are then transferred to the queue to - * re-acquire. And because conditions can only be exclusive, - * we save a field by using special value to indicate shared - * mode. - */ - Node nextWaiter; - - /** - * Returns true if node is waiting in shared mode - */ - final boolean isShared() { - return nextWaiter == SHARED; - } - - /** - * Returns previous node, or throws NullPointerException if - * null. Use when predecessor cannot be null. - * @return the predecessor of this node - */ - final Node predecessor() throws NullPointerException { - Node p = prev; - if (p == null) - throw new NullPointerException(); - else - return p; - } - - Node() { // Used to establish initial head or SHARED marker - } - - Node(Thread thread, Node mode) { // Used by addWaiter - this.nextWaiter = mode; - this.thread = thread; - } - - Node(Thread thread, int waitStatus) { // Used by Condition - this.waitStatus = waitStatus; - this.thread = thread; - } - } - - /** - * Head of the wait queue, lazily initialized. Except for - * initialization, it is modified only via method setHead. Note: - * If head exists, its waitStatus is guaranteed not to be - * CANCELLED. - */ - private transient volatile Node head; - - /** - * Tail of the wait queue, lazily initialized. Modified only via - * method enq to add new wait node. - */ - private transient volatile Node tail; - - /** - * The synchronization state. - */ - private volatile long state; - - /** - * Returns the current value of synchronization state. - * This operation has memory semantics of a <tt>volatile</tt> read. - * @return current state value - */ - protected final long getState() { - return state; - } - - /** - * Sets the value of synchronization state. - * This operation has memory semantics of a <tt>volatile</tt> write. - * @param newState the new state value - */ - protected final void setState(long newState) { - state = newState; - } - - /** - * Atomically sets synchronization state to the given updated - * value if the current state value equals the expected value. - * This operation has memory semantics of a <tt>volatile</tt> read - * and write. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that the actual - * value was not equal to the expected value. - */ - protected final boolean compareAndSetState(long expect, long update) { - // See below for intrinsics setup to support this - return unsafe.compareAndSwapLong(this, stateOffset, expect, update); - } - - // Queuing utilities - - /** - * The number of nanoseconds for which it is faster to spin - * rather than to use timed park. A rough estimate suffices - * to improve responsiveness with very short timeouts. - */ - static final long spinForTimeoutThreshold = 1000L; - - /** - * Inserts node into queue, initializing if necessary. See picture above. - * @param node the node to insert - * @return node's predecessor - */ - private Node enq(final Node node) { - for (;;) { - Node t = tail; - if (t == null) { // Must initialize - Node h = new Node(); // Dummy header - h.next = node; - node.prev = h; - if (compareAndSetHead(h)) { - tail = node; - return h; - } - } - else { - node.prev = t; - if (compareAndSetTail(t, node)) { - t.next = node; - return t; - } - } - } - } - - /** - * Creates and enqueues node for given thread and mode. - * - * @param current the thread - * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared - * @return the new node - */ - private Node addWaiter(Node mode) { - Node node = new Node(Thread.currentThread(), mode); - // Try the fast path of enq; backup to full enq on failure - Node pred = tail; - if (pred != null) { - node.prev = pred; - if (compareAndSetTail(pred, node)) { - pred.next = node; - return node; - } - } - enq(node); - return node; - } - - /** - * Sets head of queue to be node, thus dequeuing. Called only by - * acquire methods. Also nulls out unused fields for sake of GC - * and to suppress unnecessary signals and traversals. - * - * @param node the node - */ - private void setHead(Node node) { - head = node; - node.thread = null; - node.prev = null; - } - - /** - * Wakes up node's successor, if one exists. - * - * @param node the node - */ - private void unparkSuccessor(Node node) { - /* - * Try to clear status in anticipation of signalling. It is - * OK if this fails or if status is changed by waiting thread. - */ - compareAndSetWaitStatus(node, Node.SIGNAL, 0); - - /* - * Thread to unpark is held in successor, which is normally - * just the next node. But if cancelled or apparently null, - * traverse backwards from tail to find the actual - * non-cancelled successor. - */ - Node s = node.next; - if (s == null || s.waitStatus > 0) { - s = null; - for (Node t = tail; t != null && t != node; t = t.prev) - if (t.waitStatus <= 0) - s = t; - } - if (s != null) - LockSupport.unpark(s.thread); - } - - /** - * Sets head of queue, and checks if successor may be waiting - * in shared mode, if so propagating if propagate > 0. - * - * @param pred the node holding waitStatus for node - * @param node the node - * @param propagate the return value from a tryAcquireShared - */ - private void setHeadAndPropagate(Node node, long propagate) { - setHead(node); - if (propagate > 0 && node.waitStatus != 0) { - /* - * Don't bother fully figuring out successor. If it - * looks null, call unparkSuccessor anyway to be safe. - */ - Node s = node.next; - if (s == null || s.isShared()) - unparkSuccessor(node); - } - } - - // Utilities for various versions of acquire - - /** - * Cancels an ongoing attempt to acquire. - * - * @param node the node - */ - private void cancelAcquire(Node node) { - if (node != null) { // Ignore if node doesn't exist - node.thread = null; - // Can use unconditional write instead of CAS here - node.waitStatus = Node.CANCELLED; - unparkSuccessor(node); - } - } - - /** - * Checks and updates status for a node that failed to acquire. - * Returns true if thread should block. This is the main signal - * control in all acquire loops. Requires that pred == node.prev - * - * @param pred node's predecessor holding status - * @param node the node - * @return {@code true} if thread should block - */ - private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { - int s = pred.waitStatus; - if (s < 0) - /* - * This node has already set status asking a release - * to signal it, so it can safely park - */ - return true; - if (s > 0) - /* - * Predecessor was cancelled. Move up to its predecessor - * and indicate retry. - */ - node.prev = pred.prev; - else - /* - * Indicate that we need a signal, but don't park yet. Caller - * will need to retry to make sure it cannot acquire before - * parking. - */ - compareAndSetWaitStatus(pred, 0, Node.SIGNAL); - return false; - } - - /** - * Convenience method to interrupt current thread. - */ - private static void selfInterrupt() { - Thread.currentThread().interrupt(); - } - - /** - * Convenience method to park and then check if interrupted - * - * @return {@code true} if interrupted - */ - private final boolean parkAndCheckInterrupt() { - LockSupport.park(this); - return Thread.interrupted(); - } - - /* - * Various flavors of acquire, varying in exclusive/shared and - * control modes. Each is mostly the same, but annoyingly - * different. Only a little bit of factoring is possible due to - * interactions of exception mechanics (including ensuring that we - * cancel if tryAcquire throws exception) and other control, at - * least not without hurting performance too much. - */ - - /** - * Acquires in exclusive uninterruptible mode for thread already in - * queue. Used by condition wait methods as well as acquire. - * - * @param node the node - * @param arg the acquire argument - * @return {@code true} if interrupted while waiting - */ - final boolean acquireQueued(final Node node, long arg) { - try { - boolean interrupted = false; - for (;;) { - final Node p = node.predecessor(); - if (p == head && tryAcquire(arg)) { - setHead(node); - p.next = null; // help GC - return interrupted; - } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - interrupted = true; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - } - - /** - * Acquires in exclusive interruptible mode. - * @param arg the acquire argument - */ - private void doAcquireInterruptibly(long arg) - throws InterruptedException { - final Node node = addWaiter(Node.EXCLUSIVE); - try { - for (;;) { - final Node p = node.predecessor(); - if (p == head && tryAcquire(arg)) { - setHead(node); - p.next = null; // help GC - return; - } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - break; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - // Arrive here only if interrupted - cancelAcquire(node); - throw new InterruptedException(); - } - - /** - * Acquires in exclusive timed mode. - * - * @param arg the acquire argument - * @param nanosTimeout max wait time - * @return {@code true} if acquired - */ - private boolean doAcquireNanos(long arg, long nanosTimeout) - throws InterruptedException { - long lastTime = System.nanoTime(); - final Node node = addWaiter(Node.EXCLUSIVE); - try { - for (;;) { - final Node p = node.predecessor(); - if (p == head && tryAcquire(arg)) { - setHead(node); - p.next = null; // help GC - return true; - } - if (nanosTimeout <= 0) { - cancelAcquire(node); - return false; - } - if (nanosTimeout > spinForTimeoutThreshold && - shouldParkAfterFailedAcquire(p, node)) - LockSupport.parkNanos(this, nanosTimeout); - long now = System.nanoTime(); - nanosTimeout -= now - lastTime; - lastTime = now; - if (Thread.interrupted()) - break; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - // Arrive here only if interrupted - cancelAcquire(node); - throw new InterruptedException(); - } - - /** - * Acquires in shared uninterruptible mode. - * @param arg the acquire argument - */ - private void doAcquireShared(long arg) { - final Node node = addWaiter(Node.SHARED); - try { - boolean interrupted = false; - for (;;) { - final Node p = node.predecessor(); - if (p == head) { - long r = tryAcquireShared(arg); - if (r >= 0) { - setHeadAndPropagate(node, r); - p.next = null; // help GC - if (interrupted) - selfInterrupt(); - return; - } - } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - interrupted = true; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - } - - /** - * Acquires in shared interruptible mode. - * @param arg the acquire argument - */ - private void doAcquireSharedInterruptibly(long arg) - throws InterruptedException { - final Node node = addWaiter(Node.SHARED); - try { - for (;;) { - final Node p = node.predecessor(); - if (p == head) { - long r = tryAcquireShared(arg); - if (r >= 0) { - setHeadAndPropagate(node, r); - p.next = null; // help GC - return; - } - } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - break; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - // Arrive here only if interrupted - cancelAcquire(node); - throw new InterruptedException(); - } - - /** - * Acquires in shared timed mode. - * - * @param arg the acquire argument - * @param nanosTimeout max wait time - * @return {@code true} if acquired - */ - private boolean doAcquireSharedNanos(long arg, long nanosTimeout) - throws InterruptedException { - - long lastTime = System.nanoTime(); - final Node node = addWaiter(Node.SHARED); - try { - for (;;) { - final Node p = node.predecessor(); - if (p == head) { - long r = tryAcquireShared(arg); - if (r >= 0) { - setHeadAndPropagate(node, r); - p.next = null; // help GC - return true; - } - } - if (nanosTimeout <= 0) { - cancelAcquire(node); - return false; - } - if (nanosTimeout > spinForTimeoutThreshold && - shouldParkAfterFailedAcquire(p, node)) - LockSupport.parkNanos(this, nanosTimeout); - long now = System.nanoTime(); - nanosTimeout -= now - lastTime; - lastTime = now; - if (Thread.interrupted()) - break; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - // Arrive here only if interrupted - cancelAcquire(node); - throw new InterruptedException(); - } - - // Main exported methods - - /** - * Attempts to acquire in exclusive mode. This method should query - * if the state of the object permits it to be acquired in the - * exclusive mode, and if so to acquire it. - * - * <p>This method is always invoked by the thread performing - * acquire. If this method reports failure, the acquire method - * may queue the thread, if it is not already queued, until it is - * signalled by a release from some other thread. This can be used - * to implement method {@link Lock#tryLock()}. - * - * <p>The default - * implementation throws {@link UnsupportedOperationException}. - * - * @param arg the acquire argument. This value is always the one - * passed to an acquire method, or is the value saved on entry - * to a condition wait. The value is otherwise uninterpreted - * and can represent anything you like. - * @return {@code true} if successful. Upon success, this object has - * been acquired. - * @throws IllegalMonitorStateException if acquiring would place this - * synchronizer in an illegal state. This exception must be - * thrown in a consistent fashion for synchronization to work - * correctly. - * @throws UnsupportedOperationException if exclusive mode is not supported - */ - protected boolean tryAcquire(long arg) { - throw new UnsupportedOperationException(); - } - - /** - * Attempts to set the state to reflect a release in exclusive - * mode. - * - * <p>This method is always invoked by the thread performing release. - * - * <p>The default implementation throws - * {@link UnsupportedOperationException}. - * - * @param arg the release argument. This value is always the one - * passed to a release method, or the current state value upon - * entry to a condition wait. The value is otherwise - * uninterpreted and can represent anything you like. - * @return {@code true} if this object is now in a fully released - * state, so that any waiting threads may attempt to acquire; - * and {@code false} otherwise. - * @throws IllegalMonitorStateException if releasing would place this - * synchronizer in an illegal state. This exception must be - * thrown in a consistent fashion for synchronization to work - * correctly. - * @throws UnsupportedOperationException if exclusive mode is not supported - */ - protected boolean tryRelease(long arg) { - throw new UnsupportedOperationException(); - } - - /** - * Attempts to acquire in shared mode. This method should query if - * the state of the object permits it to be acquired in the shared - * mode, and if so to acquire it. - * - * <p>This method is always invoked by the thread performing - * acquire. If this method reports failure, the acquire method - * may queue the thread, if it is not already queued, until it is - * signalled by a release from some other thread. - * - * <p>The default implementation throws {@link - * UnsupportedOperationException}. - * - * @param arg the acquire argument. This value is always the one - * passed to an acquire method, or is the value saved on entry - * to a condition wait. The value is otherwise uninterpreted - * and can represent anything you like. - * @return a negative value on failure; zero if acquisition in shared - * mode succeeded but no subsequent shared-mode acquire can - * succeed; and a positive value if acquisition in shared - * mode succeeded and subsequent shared-mode acquires might - * also succeed, in which case a subsequent waiting thread - * must check availability. (Support for three different - * return values enables this method to be used in contexts - * where acquires only sometimes act exclusively.) Upon - * success, this object has been acquired. - * @throws IllegalMonitorStateException if acquiring would place this - * synchronizer in an illegal state. This exception must be - * thrown in a consistent fashion for synchronization to work - * correctly. - * @throws UnsupportedOperationException if shared mode is not supported - */ - protected long tryAcquireShared(long arg) { - throw new UnsupportedOperationException(); - } - - /** - * Attempts to set the state to reflect a release in shared mode. - * - * <p>This method is always invoked by the thread performing release. - * - * <p>The default implementation throws - * {@link UnsupportedOperationException}. - * - * @param arg the release argument. This value is always the one - * passed to a release method, or the current state value upon - * entry to a condition wait. The value is otherwise - * uninterpreted and can represent anything you like. - * @return {@code true} if this release of shared mode may permit a - * waiting acquire (shared or exclusive) to succeed; and - * {@code false} otherwise - * @throws IllegalMonitorStateException if releasing would place this - * synchronizer in an illegal state. This exception must be - * thrown in a consistent fashion for synchronization to work - * correctly. - * @throws UnsupportedOperationException if shared mode is not supported - */ - protected boolean tryReleaseShared(long arg) { - throw new UnsupportedOperationException(); - } - - /** - * Returns {@code true} if synchronization is held exclusively with - * respect to the current (calling) thread. This method is invoked - * upon each call to a non-waiting {@link ConditionObject} method. - * (Waiting methods instead invoke {@link #release}.) - * - * <p>The default implementation throws {@link - * UnsupportedOperationException}. This method is invoked - * internally only within {@link ConditionObject} methods, so need - * not be defined if conditions are not used. - * - * @return {@code true} if synchronization is held exclusively; - * {@code false} otherwise - * @throws UnsupportedOperationException if conditions are not supported - */ - protected boolean isHeldExclusively() { - throw new UnsupportedOperationException(); - } - - /** - * Acquires in exclusive mode, ignoring interrupts. Implemented - * by invoking at least once {@link #tryAcquire}, - * returning on success. Otherwise the thread is queued, possibly - * repeatedly blocking and unblocking, invoking {@link - * #tryAcquire} until success. This method can be used - * to implement method {@link Lock#lock}. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquire} but is otherwise uninterpreted and - * can represent anything you like. - */ - public final void acquire(long arg) { - if (!tryAcquire(arg) && - acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) - selfInterrupt(); - } - - /** - * Acquires in exclusive mode, aborting if interrupted. - * Implemented by first checking interrupt status, then invoking - * at least once {@link #tryAcquire}, returning on - * success. Otherwise the thread is queued, possibly repeatedly - * blocking and unblocking, invoking {@link #tryAcquire} - * until success or the thread is interrupted. This method can be - * used to implement method {@link Lock#lockInterruptibly}. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquire} but is otherwise uninterpreted and - * can represent anything you like. - * @throws InterruptedException if the current thread is interrupted - */ - public final void acquireInterruptibly(long arg) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - if (!tryAcquire(arg)) - doAcquireInterruptibly(arg); - } - - /** - * Attempts to acquire in exclusive mode, aborting if interrupted, - * and failing if the given timeout elapses. Implemented by first - * checking interrupt status, then invoking at least once {@link - * #tryAcquire}, returning on success. Otherwise, the thread is - * queued, possibly repeatedly blocking and unblocking, invoking - * {@link #tryAcquire} until success or the thread is interrupted - * or the timeout elapses. This method can be used to implement - * method {@link Lock#tryLock(long, TimeUnit)}. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquire} but is otherwise uninterpreted and - * can represent anything you like. - * @param nanosTimeout the maximum number of nanoseconds to wait - * @return {@code true} if acquired; {@code false} if timed out - * @throws InterruptedException if the current thread is interrupted - */ - public final boolean tryAcquireNanos(long arg, long nanosTimeout) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - return tryAcquire(arg) || - doAcquireNanos(arg, nanosTimeout); - } - - /** - * Releases in exclusive mode. Implemented by unblocking one or - * more threads if {@link #tryRelease} returns true. - * This method can be used to implement method {@link Lock#unlock}. - * - * @param arg the release argument. This value is conveyed to - * {@link #tryRelease} but is otherwise uninterpreted and - * can represent anything you like. - * @return the value returned from {@link #tryRelease} - */ - public final boolean release(long arg) { - if (tryRelease(arg)) { - Node h = head; - if (h != null && h.waitStatus != 0) - unparkSuccessor(h); - return true; - } - return false; - } - - /** - * Acquires in shared mode, ignoring interrupts. Implemented by - * first invoking at least once {@link #tryAcquireShared}, - * returning on success. Otherwise the thread is queued, possibly - * repeatedly blocking and unblocking, invoking {@link - * #tryAcquireShared} until success. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquireShared} but is otherwise uninterpreted - * and can represent anything you like. - */ - public final void acquireShared(long arg) { - if (tryAcquireShared(arg) < 0) - doAcquireShared(arg); - } - - /** - * Acquires in shared mode, aborting if interrupted. Implemented - * by first checking interrupt status, then invoking at least once - * {@link #tryAcquireShared}, returning on success. Otherwise the - * thread is queued, possibly repeatedly blocking and unblocking, - * invoking {@link #tryAcquireShared} until success or the thread - * is interrupted. - * @param arg the acquire argument. - * This value is conveyed to {@link #tryAcquireShared} but is - * otherwise uninterpreted and can represent anything - * you like. - * @throws InterruptedException if the current thread is interrupted - */ - public final void acquireSharedInterruptibly(long arg) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - if (tryAcquireShared(arg) < 0) - doAcquireSharedInterruptibly(arg); - } - - /** - * Attempts to acquire in shared mode, aborting if interrupted, and - * failing if the given timeout elapses. Implemented by first - * checking interrupt status, then invoking at least once {@link - * #tryAcquireShared}, returning on success. Otherwise, the - * thread is queued, possibly repeatedly blocking and unblocking, - * invoking {@link #tryAcquireShared} until success or the thread - * is interrupted or the timeout elapses. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquireShared} but is otherwise uninterpreted - * and can represent anything you like. - * @param nanosTimeout the maximum number of nanoseconds to wait - * @return {@code true} if acquired; {@code false} if timed out - * @throws InterruptedException if the current thread is interrupted - */ - public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - return tryAcquireShared(arg) >= 0 || - doAcquireSharedNanos(arg, nanosTimeout); - } - - /** - * Releases in shared mode. Implemented by unblocking one or more - * threads if {@link #tryReleaseShared} returns true. - * - * @param arg the release argument. This value is conveyed to - * {@link #tryReleaseShared} but is otherwise uninterpreted - * and can represent anything you like. - * @return the value returned from {@link #tryReleaseShared} - */ - public final boolean releaseShared(long arg) { - if (tryReleaseShared(arg)) { - Node h = head; - if (h != null && h.waitStatus != 0) - unparkSuccessor(h); - return true; - } - return false; - } - - // Queue inspection methods - - /** - * Queries whether any threads are waiting to acquire. Note that - * because cancellations due to interrupts and timeouts may occur - * at any time, a {@code true} return does not guarantee that any - * other thread will ever acquire. - * - * <p>In this implementation, this operation returns in - * constant time. - * - * @return {@code true} if there may be other threads waiting to acquire - */ - public final boolean hasQueuedThreads() { - return head != tail; - } - - /** - * Queries whether any threads have ever contended to acquire this - * synchronizer; that is if an acquire method has ever blocked. - * - * <p>In this implementation, this operation returns in - * constant time. - * - * @return {@code true} if there has ever been contention - */ - public final boolean hasContended() { - return head != null; - } - - /** - * Returns the first (longest-waiting) thread in the queue, or - * {@code null} if no threads are currently queued. - * - * <p>In this implementation, this operation normally returns in - * constant time, but may iterate upon contention if other threads are - * concurrently modifying the queue. - * - * @return the first (longest-waiting) thread in the queue, or - * {@code null} if no threads are currently queued - */ - public final Thread getFirstQueuedThread() { - // handle only fast path, else relay - return (head == tail)? null : fullGetFirstQueuedThread(); - } - - /** - * Version of getFirstQueuedThread called when fastpath fails - */ - private Thread fullGetFirstQueuedThread() { - /* - * The first node is normally h.next. Try to get its - * thread field, ensuring consistent reads: If thread - * field is nulled out or s.prev is no longer head, then - * some other thread(s) concurrently performed setHead in - * between some of our reads. We try this twice before - * resorting to traversal. - */ - Node h, s; - Thread st; - if (((h = head) != null && (s = h.next) != null && - s.prev == head && (st = s.thread) != null) || - ((h = head) != null && (s = h.next) != null && - s.prev == head && (st = s.thread) != null)) - return st; - - /* - * Head's next field might not have been set yet, or may have - * been unset after setHead. So we must check to see if tail - * is actually first node. If not, we continue on, safely - * traversing from tail back to head to find first, - * guaranteeing termination. - */ - - Node t = tail; - Thread firstThread = null; - while (t != null && t != head) { - Thread tt = t.thread; - if (tt != null) - firstThread = tt; - t = t.prev; - } - return firstThread; - } - - /** - * Returns true if the given thread is currently queued. - * - * <p>This implementation traverses the queue to determine - * presence of the given thread. - * - * @param thread the thread - * @return {@code true} if the given thread is on the queue - * @throws NullPointerException if the thread is null - */ - public final boolean isQueued(Thread thread) { - if (thread == null) - throw new NullPointerException(); - for (Node p = tail; p != null; p = p.prev) - if (p.thread == thread) - return true; - return false; - } - - /** - * Return {@code true} if the apparent first queued thread, if one - * exists, is not waiting in exclusive mode. Used only as a heuristic - * in ReentrantReadWriteLock. - */ - final boolean apparentlyFirstQueuedIsExclusive() { - Node h, s; - return ((h = head) != null && (s = h.next) != null && - s.nextWaiter != Node.SHARED); - } - - /** - * Return {@code true} if the queue is empty or if the given thread - * is at the head of the queue. This is reliable only if - * <tt>current</tt> is actually Thread.currentThread() of caller. - */ - final boolean isFirst(Thread current) { - Node h, s; - return ((h = head) == null || - ((s = h.next) != null && s.thread == current) || - fullIsFirst(current)); - } - - final boolean fullIsFirst(Thread current) { - // same idea as fullGetFirstQueuedThread - Node h, s; - Thread firstThread = null; - if (((h = head) != null && (s = h.next) != null && - s.prev == head && (firstThread = s.thread) != null)) - return firstThread == current; - Node t = tail; - while (t != null && t != head) { - Thread tt = t.thread; - if (tt != null) - firstThread = tt; - t = t.prev; - } - return firstThread == current || firstThread == null; - } - - - // Instrumentation and monitoring methods - - /** - * Returns an estimate of the number of threads waiting to - * acquire. The value is only an estimate because the number of - * threads may change dynamically while this method traverses - * internal data structures. This method is designed for use in - * monitoring system state, not for synchronization - * control. - * - * @return the estimated number of threads waiting to acquire - */ - public final int getQueueLength() { - int n = 0; - for (Node p = tail; p != null; p = p.prev) { - if (p.thread != null) - ++n; - } - return n; - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire. Because the actual set of threads may change - * dynamically while constructing this result, the returned - * collection is only a best-effort estimate. The elements of the - * returned collection are in no particular order. This method is - * designed to facilitate construction of subclasses that provide - * more extensive monitoring facilities. - * - * @return the collection of threads - */ - public final Collection<Thread> getQueuedThreads() { - ArrayList<Thread> list = new ArrayList<Thread>(); - for (Node p = tail; p != null; p = p.prev) { - Thread t = p.thread; - if (t != null) - list.add(t); - } - return list; - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire in exclusive mode. This has the same properties - * as {@link #getQueuedThreads} except that it only returns - * those threads waiting due to an exclusive acquire. - * - * @return the collection of threads - */ - public final Collection<Thread> getExclusiveQueuedThreads() { - ArrayList<Thread> list = new ArrayList<Thread>(); - for (Node p = tail; p != null; p = p.prev) { - if (!p.isShared()) { - Thread t = p.thread; - if (t != null) - list.add(t); - } - } - return list; - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire in shared mode. This has the same properties - * as {@link #getQueuedThreads} except that it only returns - * those threads waiting due to a shared acquire. - * - * @return the collection of threads - */ - public final Collection<Thread> getSharedQueuedThreads() { - ArrayList<Thread> list = new ArrayList<Thread>(); - for (Node p = tail; p != null; p = p.prev) { - if (p.isShared()) { - Thread t = p.thread; - if (t != null) - list.add(t); - } - } - return list; - } - - /** - * Returns a string identifying this synchronizer, as well as its state. - * The state, in brackets, includes the String {@code "State ="} - * followed by the current value of {@link #getState}, and either - * {@code "nonempty"} or {@code "empty"} depending on whether the - * queue is empty. - * - * @return a string identifying this synchronizer, as well as its state - */ - public String toString() { - long s = getState(); - String q = hasQueuedThreads()? "non" : ""; - return super.toString() + - "[State = " + s + ", " + q + "empty queue]"; - } - - - // Internal support methods for Conditions - - /** - * Returns true if a node, always one that was initially placed on - * a condition queue, is now waiting to reacquire on sync queue. - * @param node the node - * @return true if is reacquiring - */ - final boolean isOnSyncQueue(Node node) { - if (node.waitStatus == Node.CONDITION || node.prev == null) - return false; - if (node.next != null) // If has successor, it must be on queue - return true; - /* - * node.prev can be non-null, but not yet on queue because - * the CAS to place it on queue can fail. So we have to - * traverse from tail to make sure it actually made it. It - * will always be near the tail in calls to this method, and - * unless the CAS failed (which is unlikely), it will be - * there, so we hardly ever traverse much. - */ - return findNodeFromTail(node); - } - - /** - * Returns true if node is on sync queue by searching backwards from tail. - * Called only when needed by isOnSyncQueue. - * @return true if present - */ - private boolean findNodeFromTail(Node node) { - Node t = tail; - for (;;) { - if (t == node) - return true; - if (t == null) - return false; - t = t.prev; - } - } - - /** - * Transfers a node from a condition queue onto sync queue. - * Returns true if successful. - * @param node the node - * @return true if successfully transferred (else the node was - * cancelled before signal). - */ - final boolean transferForSignal(Node node) { - /* - * If cannot change waitStatus, the node has been cancelled. - */ - if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) - return false; - - /* - * Splice onto queue and try to set waitStatus of predecessor to - * indicate that thread is (probably) waiting. If cancelled or - * attempt to set waitStatus fails, wake up to resync (in which - * case the waitStatus can be transiently and harmlessly wrong). - */ - Node p = enq(node); - int c = p.waitStatus; - if (c > 0 || !compareAndSetWaitStatus(p, c, Node.SIGNAL)) - LockSupport.unpark(node.thread); - return true; - } - - /** - * Transfers node, if necessary, to sync queue after a cancelled - * wait. Returns true if thread was cancelled before being - * signalled. - * @param current the waiting thread - * @param node its node - * @return true if cancelled before the node was signalled. - */ - final boolean transferAfterCancelledWait(Node node) { - if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { - enq(node); - return true; - } - /* - * If we lost out to a signal(), then we can't proceed - * until it finishes its enq(). Cancelling during an - * incomplete transfer is both rare and transient, so just - * spin. - */ - while (!isOnSyncQueue(node)) - Thread.yield(); - return false; - } - - /** - * Invokes release with current state value; returns saved state. - * Cancels node and throws exception on failure. - * @param node the condition node for this wait - * @return previous sync state - */ - final long fullyRelease(Node node) { - try { - long savedState = getState(); - if (release(savedState)) - return savedState; - } catch (RuntimeException ex) { - node.waitStatus = Node.CANCELLED; - throw ex; - } - // reach here if release fails - node.waitStatus = Node.CANCELLED; - throw new IllegalMonitorStateException(); - } - - // Instrumentation methods for conditions - - /** - * Queries whether the given ConditionObject - * uses this synchronizer as its lock. - * - * @param condition the condition - * @return <tt>true</tt> if owned - * @throws NullPointerException if the condition is null - */ - public final boolean owns(ConditionObject condition) { - if (condition == null) - throw new NullPointerException(); - return condition.isOwnedBy(this); - } - - /** - * Queries whether any threads are waiting on the given condition - * associated with this synchronizer. Note that because timeouts - * and interrupts may occur at any time, a <tt>true</tt> return - * does not guarantee that a future <tt>signal</tt> will awaken - * any threads. This method is designed primarily for use in - * monitoring of the system state. - * - * @param condition the condition - * @return <tt>true</tt> if there are any waiting threads - * @throws IllegalMonitorStateException if exclusive synchronization - * is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this synchronizer - * @throws NullPointerException if the condition is null - */ - public final boolean hasWaiters(ConditionObject condition) { - if (!owns(condition)) - throw new IllegalArgumentException("Not owner"); - return condition.hasWaiters(); - } - - /** - * Returns an estimate of the number of threads waiting on the - * given condition associated with this synchronizer. Note that - * because timeouts and interrupts may occur at any time, the - * estimate serves only as an upper bound on the actual number of - * waiters. This method is designed for use in monitoring of the - * system state, not for synchronization control. - * - * @param condition the condition - * @return the estimated number of waiting threads - * @throws IllegalMonitorStateException if exclusive synchronization - * is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this synchronizer - * @throws NullPointerException if the condition is null - */ - public final int getWaitQueueLength(ConditionObject condition) { - if (!owns(condition)) - throw new IllegalArgumentException("Not owner"); - return condition.getWaitQueueLength(); - } - - /** - * Returns a collection containing those threads that may be - * waiting on the given condition associated with this - * synchronizer. Because the actual set of threads may change - * dynamically while constructing this result, the returned - * collection is only a best-effort estimate. The elements of the - * returned collection are in no particular order. - * - * @param condition the condition - * @return the collection of threads - * @throws IllegalMonitorStateException if exclusive synchronization - * is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this synchronizer - * @throws NullPointerException if the condition is null - */ - public final Collection<Thread> getWaitingThreads(ConditionObject condition) { - if (!owns(condition)) - throw new IllegalArgumentException("Not owner"); - return condition.getWaitingThreads(); - } - - /** - * Condition implementation for a {@link - * AbstractQueuedLongSynchronizer} serving as the basis of a {@link - * Lock} implementation. - * - * <p>Method documentation for this class describes mechanics, - * not behavioral specifications from the point of view of Lock - * and Condition users. Exported versions of this class will in - * general need to be accompanied by documentation describing - * condition semantics that rely on those of the associated - * <tt>AbstractQueuedLongSynchronizer</tt>. - * - * <p>This class is Serializable, but all fields are transient, - * so deserialized conditions have no waiters. - * - * @since 1.6 - */ - public class ConditionObject implements Condition, java.io.Serializable { - private static final long serialVersionUID = 1173984872572414699L; - /** First node of condition queue. */ - private transient Node firstWaiter; - /** Last node of condition queue. */ - private transient Node lastWaiter; - - /** - * Creates a new <tt>ConditionObject</tt> instance. - */ - public ConditionObject() { } - - // Internal methods - - /** - * Adds a new waiter to wait queue. - * @return its new wait node - */ - private Node addConditionWaiter() { - Node node = new Node(Thread.currentThread(), Node.CONDITION); - Node t = lastWaiter; - if (t == null) - firstWaiter = node; - else - t.nextWaiter = node; - lastWaiter = node; - return node; - } - - /** - * Removes and transfers nodes until hit non-cancelled one or - * null. Split out from signal in part to encourage compilers - * to inline the case of no waiters. - * @param first (non-null) the first node on condition queue - */ - private void doSignal(Node first) { - do { - if ( (firstWaiter = first.nextWaiter) == null) - lastWaiter = null; - first.nextWaiter = null; - } while (!transferForSignal(first) && - (first = firstWaiter) != null); - } - - /** - * Removes and transfers all nodes. - * @param first (non-null) the first node on condition queue - */ - private void doSignalAll(Node first) { - lastWaiter = firstWaiter = null; - do { - Node next = first.nextWaiter; - first.nextWaiter = null; - transferForSignal(first); - first = next; - } while (first != null); - } - - /** - * Returns true if given node is on this condition queue. - * Call only when holding lock. - */ - private boolean isOnConditionQueue(Node node) { - return node.next != null || node == lastWaiter; - } - - /** - * Unlinks a cancelled waiter node from condition queue. This - * is called when cancellation occurred during condition wait, - * not lock wait, and is called only after lock has been - * re-acquired by a cancelled waiter and the node is not known - * to already have been dequeued. It is needed to avoid - * garbage retention in the absence of signals. So even though - * it may require a full traversal, it comes into play only - * when timeouts or cancellations occur in the absence of - * signals. - */ - private void unlinkCancelledWaiter(Node node) { - Node t = firstWaiter; - Node trail = null; - while (t != null) { - if (t == node) { - Node next = t.nextWaiter; - if (trail == null) - firstWaiter = next; - else - trail.nextWaiter = next; - if (lastWaiter == node) - lastWaiter = trail; - break; - } - trail = t; - t = t.nextWaiter; - } - } - - // public methods - - /** - * Moves the longest-waiting thread, if one exists, from the - * wait queue for this condition to the wait queue for the - * owning lock. - * - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - public final void signal() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - Node first = firstWaiter; - if (first != null) - doSignal(first); - } - - /** - * Moves all threads from the wait queue for this condition to - * the wait queue for the owning lock. - * - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - public final void signalAll() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - Node first = firstWaiter; - if (first != null) - doSignalAll(first); - } - - /** - * Implements uninterruptible condition wait. - * <ol> - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * </ol> - */ - public final void awaitUninterruptibly() { - Node node = addConditionWaiter(); - long savedState = fullyRelease(node); - boolean interrupted = false; - while (!isOnSyncQueue(node)) { - LockSupport.park(this); - if (Thread.interrupted()) - interrupted = true; - } - if (acquireQueued(node, savedState) || interrupted) - selfInterrupt(); - } - - /* - * For interruptible waits, we need to track whether to throw - * InterruptedException, if interrupted while blocked on - * condition, versus reinterrupt current thread, if - * interrupted while blocked waiting to re-acquire. - */ - - /** Mode meaning to reinterrupt on exit from wait */ - private static final int REINTERRUPT = 1; - /** Mode meaning to throw InterruptedException on exit from wait */ - private static final int THROW_IE = -1; - - /** - * Checks for interrupt, returning THROW_IE if interrupted - * before signalled, REINTERRUPT if after signalled, or - * 0 if not interrupted. - */ - private int checkInterruptWhileWaiting(Node node) { - return (Thread.interrupted()) ? - ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) : - 0; - } - - /** - * Throws InterruptedException, reinterrupts current thread, or - * does nothing, depending on mode. - */ - private void reportInterruptAfterWait(int interruptMode) - throws InterruptedException { - if (interruptMode == THROW_IE) - throw new InterruptedException(); - else if (interruptMode == REINTERRUPT) - selfInterrupt(); - } - - /** - * Implements interruptible condition wait. - * <ol> - * <li> If current thread is interrupted, throw InterruptedException - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled or interrupted - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * <li> If interrupted while blocked in step 4, throw exception - * </ol> - */ - public final void await() throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - Node node = addConditionWaiter(); - long savedState = fullyRelease(node); - int interruptMode = 0; - while (!isOnSyncQueue(node)) { - LockSupport.park(this); - if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) - break; - } - if (acquireQueued(node, savedState) && interruptMode != THROW_IE) - interruptMode = REINTERRUPT; - if (isOnConditionQueue(node)) - unlinkCancelledWaiter(node); - if (interruptMode != 0) - reportInterruptAfterWait(interruptMode); - } - - /** - * Implements timed condition wait. - * <ol> - * <li> If current thread is interrupted, throw InterruptedException - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled, interrupted, or timed out - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * <li> If interrupted while blocked in step 4, throw InterruptedException - * </ol> - */ - public final long awaitNanos(long nanosTimeout) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - Node node = addConditionWaiter(); - long savedState = fullyRelease(node); - long lastTime = System.nanoTime(); - int interruptMode = 0; - while (!isOnSyncQueue(node)) { - if (nanosTimeout <= 0L) { - transferAfterCancelledWait(node); - break; - } - LockSupport.parkNanos(this, nanosTimeout); - if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) - break; - - long now = System.nanoTime(); - nanosTimeout -= now - lastTime; - lastTime = now; - } - if (acquireQueued(node, savedState) && interruptMode != THROW_IE) - interruptMode = REINTERRUPT; - if (isOnConditionQueue(node)) - unlinkCancelledWaiter(node); - if (interruptMode != 0) - reportInterruptAfterWait(interruptMode); - return nanosTimeout - (System.nanoTime() - lastTime); - } - - /** - * Implements absolute timed condition wait. - * <ol> - * <li> If current thread is interrupted, throw InterruptedException - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled, interrupted, or timed out - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * <li> If interrupted while blocked in step 4, throw InterruptedException - * <li> If timed out while blocked in step 4, return false, else true - * </ol> - */ - public final boolean awaitUntil(Date deadline) throws InterruptedException { - if (deadline == null) - throw new NullPointerException(); - long abstime = deadline.getTime(); - if (Thread.interrupted()) - throw new InterruptedException(); - Node node = addConditionWaiter(); - long savedState = fullyRelease(node); - boolean timedout = false; - int interruptMode = 0; - while (!isOnSyncQueue(node)) { - if (System.currentTimeMillis() > abstime) { - timedout = transferAfterCancelledWait(node); - break; - } - LockSupport.parkUntil(this, abstime); - if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) - break; - } - if (acquireQueued(node, savedState) && interruptMode != THROW_IE) - interruptMode = REINTERRUPT; - if (isOnConditionQueue(node)) - unlinkCancelledWaiter(node); - if (interruptMode != 0) - reportInterruptAfterWait(interruptMode); - return !timedout; - } - - /** - * Implements timed condition wait. - * <ol> - * <li> If current thread is interrupted, throw InterruptedException - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled, interrupted, or timed out - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * <li> If interrupted while blocked in step 4, throw InterruptedException - * <li> If timed out while blocked in step 4, return false, else true - * </ol> - */ - public final boolean await(long time, TimeUnit unit) throws InterruptedException { - if (unit == null) - throw new NullPointerException(); - long nanosTimeout = unit.toNanos(time); - if (Thread.interrupted()) - throw new InterruptedException(); - Node node = addConditionWaiter(); - long savedState = fullyRelease(node); - long lastTime = System.nanoTime(); - boolean timedout = false; - int interruptMode = 0; - while (!isOnSyncQueue(node)) { - if (nanosTimeout <= 0L) { - timedout = transferAfterCancelledWait(node); - break; - } - LockSupport.parkNanos(this, nanosTimeout); - if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) - break; - long now = System.nanoTime(); - nanosTimeout -= now - lastTime; - lastTime = now; - } - if (acquireQueued(node, savedState) && interruptMode != THROW_IE) - interruptMode = REINTERRUPT; - if (isOnConditionQueue(node)) - unlinkCancelledWaiter(node); - if (interruptMode != 0) - reportInterruptAfterWait(interruptMode); - return !timedout; - } - - // support for instrumentation - - /** - * Returns true if this condition was created by the given - * synchronization object. - * - * @return {@code true} if owned - */ - final boolean isOwnedBy(AbstractQueuedLongSynchronizer sync) { - return sync == AbstractQueuedLongSynchronizer.this; - } - - /** - * Queries whether any threads are waiting on this condition. - * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters}. - * - * @return {@code true} if there are any waiting threads - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - protected final boolean hasWaiters() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - for (Node w = firstWaiter; w != null; w = w.nextWaiter) { - if (w.waitStatus == Node.CONDITION) - return true; - } - return false; - } - - /** - * Returns an estimate of the number of threads waiting on - * this condition. - * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength}. - * - * @return the estimated number of waiting threads - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - protected final int getWaitQueueLength() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - int n = 0; - for (Node w = firstWaiter; w != null; w = w.nextWaiter) { - if (w.waitStatus == Node.CONDITION) - ++n; - } - return n; - } - - /** - * Returns a collection containing those threads that may be - * waiting on this Condition. - * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads}. - * - * @return the collection of threads - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - protected final Collection<Thread> getWaitingThreads() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - ArrayList<Thread> list = new ArrayList<Thread>(); - for (Node w = firstWaiter; w != null; w = w.nextWaiter) { - if (w.waitStatus == Node.CONDITION) { - Thread t = w.thread; - if (t != null) - list.add(t); - } - } - return list; - } - } - - /** - * Setup to support compareAndSet. We need to natively implement - * this here: For the sake of permitting future enhancements, we - * cannot explicitly subclass AtomicLong, which would be - * efficient and useful otherwise. So, as the lesser of evils, we - * natively implement using hotspot intrinsics API. And while we - * are at it, we do the same for other CASable fields (which could - * otherwise be done with atomic field updaters). - */ - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long stateOffset; - private static final long headOffset; - private static final long tailOffset; - private static final long waitStatusOffset; - - static { - try { - stateOffset = unsafe.objectFieldOffset - (AbstractQueuedLongSynchronizer.class.getDeclaredField("state")); - headOffset = unsafe.objectFieldOffset - (AbstractQueuedLongSynchronizer.class.getDeclaredField("head")); - tailOffset = unsafe.objectFieldOffset - (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail")); - waitStatusOffset = unsafe.objectFieldOffset - (Node.class.getDeclaredField("waitStatus")); - - } catch (Exception ex) { throw new Error(ex); } - } - - /** - * CAS head field. Used only by enq - */ - private final boolean compareAndSetHead(Node update) { - return unsafe.compareAndSwapObject(this, headOffset, null, update); - } - - /** - * CAS tail field. Used only by enq - */ - private final boolean compareAndSetTail(Node expect, Node update) { - return unsafe.compareAndSwapObject(this, tailOffset, expect, update); - } - - /** - * CAS waitStatus field of a node. - */ - private final static boolean compareAndSetWaitStatus(Node node, - int expect, - int update) { - return unsafe.compareAndSwapInt(node, waitStatusOffset, - expect, update); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java deleted file mode 100644 index 647f4fc..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ /dev/null @@ -1,2159 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import sun.misc.Unsafe; - -/** - * Provides a framework for implementing blocking locks and related - * synchronizers (semaphores, events, etc) that rely on - * first-in-first-out (FIFO) wait queues. This class is designed to - * be a useful basis for most kinds of synchronizers that rely on a - * single atomic <tt>int</tt> value to represent state. Subclasses - * must define the protected methods that change this state, and which - * define what that state means in terms of this object being acquired - * or released. Given these, the other methods in this class carry - * out all queuing and blocking mechanics. Subclasses can maintain - * other state fields, but only the atomically updated <tt>int</tt> - * value manipulated using methods {@link #getState}, {@link - * #setState} and {@link #compareAndSetState} is tracked with respect - * to synchronization. - * - * <p>Subclasses should be defined as non-public internal helper - * classes that are used to implement the synchronization properties - * of their enclosing class. Class - * <tt>AbstractQueuedSynchronizer</tt> does not implement any - * synchronization interface. Instead it defines methods such as - * {@link #acquireInterruptibly} that can be invoked as - * appropriate by concrete locks and related synchronizers to - * implement their public methods. - * - * <p>This class supports either or both a default <em>exclusive</em> - * mode and a <em>shared</em> mode. When acquired in exclusive mode, - * attempted acquires by other threads cannot succeed. Shared mode - * acquires by multiple threads may (but need not) succeed. This class - * does not "understand" these differences except in the - * mechanical sense that when a shared mode acquire succeeds, the next - * waiting thread (if one exists) must also determine whether it can - * acquire as well. Threads waiting in the different modes share the - * same FIFO queue. Usually, implementation subclasses support only - * one of these modes, but both can come into play for example in a - * {@link ReadWriteLock}. Subclasses that support only exclusive or - * only shared modes need not define the methods supporting the unused mode. - * - * <p>This class defines a nested {@link ConditionObject} class that - * can be used as a {@link Condition} implementation by subclasses - * supporting exclusive mode for which method {@link - * #isHeldExclusively} reports whether synchronization is exclusively - * held with respect to the current thread, method {@link #release} - * invoked with the current {@link #getState} value fully releases - * this object, and {@link #acquire}, given this saved state value, - * eventually restores this object to its previous acquired state. No - * <tt>AbstractQueuedSynchronizer</tt> method otherwise creates such a - * condition, so if this constraint cannot be met, do not use it. The - * behavior of {@link ConditionObject} depends of course on the - * semantics of its synchronizer implementation. - * - * <p>This class provides inspection, instrumentation, and monitoring - * methods for the internal queue, as well as similar methods for - * condition objects. These can be exported as desired into classes - * using an <tt>AbstractQueuedSynchronizer</tt> for their - * synchronization mechanics. - * - * <p>Serialization of this class stores only the underlying atomic - * integer maintaining state, so deserialized objects have empty - * thread queues. Typical subclasses requiring serializability will - * define a <tt>readObject</tt> method that restores this to a known - * initial state upon deserialization. - * - * <h3>Usage</h3> - * - * <p>To use this class as the basis of a synchronizer, redefine the - * following methods, as applicable, by inspecting and/or modifying - * the synchronization state using {@link #getState}, {@link - * #setState} and/or {@link #compareAndSetState}: - * - * <ul> - * <li> {@link #tryAcquire} - * <li> {@link #tryRelease} - * <li> {@link #tryAcquireShared} - * <li> {@link #tryReleaseShared} - * <li> {@link #isHeldExclusively} - *</ul> - * - * Each of these methods by default throws {@link - * UnsupportedOperationException}. Implementations of these methods - * must be internally thread-safe, and should in general be short and - * not block. Defining these methods is the <em>only</em> supported - * means of using this class. All other methods are declared - * <tt>final</tt> because they cannot be independently varied. - * - * <p>You may also find the inherited methods from {@link - * AbstractOwnableSynchronizer} useful to keep track of the thread - * owning an exclusive synchronizer. You are encouraged to use them - * -- this enables monitoring and diagnostic tools to assist users in - * determining which threads hold locks. - * - * <p>Even though this class is based on an internal FIFO queue, it - * does not automatically enforce FIFO acquisition policies. The core - * of exclusive synchronization takes the form: - * - * <pre> - * Acquire: - * while (!tryAcquire(arg)) { - * <em>enqueue thread if it is not already queued</em>; - * <em>possibly block current thread</em>; - * } - * - * Release: - * if (tryRelease(arg)) - * <em>unblock the first queued thread</em>; - * </pre> - * - * (Shared mode is similar but may involve cascading signals.) - * - * <p>Because checks in acquire are invoked before enqueuing, a newly - * acquiring thread may <em>barge</em> ahead of others that are - * blocked and queued. However, you can, if desired, define - * <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to disable - * barging by internally invoking one or more of the inspection - * methods. In particular, a strict FIFO lock can define - * <tt>tryAcquire</tt> to immediately return <tt>false</tt> if {@link - * #getFirstQueuedThread} does not return the current thread. A - * normally preferable non-strict fair version can immediately return - * <tt>false</tt> only if {@link #hasQueuedThreads} returns - * <tt>true</tt> and <tt>getFirstQueuedThread</tt> is not the current - * thread; or equivalently, that <tt>getFirstQueuedThread</tt> is both - * non-null and not the current thread. Further variations are - * possible. - * - * <p>Throughput and scalability are generally highest for the - * default barging (also known as <em>greedy</em>, - * <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy. - * While this is not guaranteed to be fair or starvation-free, earlier - * queued threads are allowed to recontend before later queued - * threads, and each recontention has an unbiased chance to succeed - * against incoming threads. Also, while acquires do not - * "spin" in the usual sense, they may perform multiple - * invocations of <tt>tryAcquire</tt> interspersed with other - * computations before blocking. This gives most of the benefits of - * spins when exclusive synchronization is only briefly held, without - * most of the liabilities when it isn't. If so desired, you can - * augment this by preceding calls to acquire methods with - * "fast-path" checks, possibly prechecking {@link #hasContended} - * and/or {@link #hasQueuedThreads} to only do so if the synchronizer - * is likely not to be contended. - * - * <p>This class provides an efficient and scalable basis for - * synchronization in part by specializing its range of use to - * synchronizers that can rely on <tt>int</tt> state, acquire, and - * release parameters, and an internal FIFO wait queue. When this does - * not suffice, you can build synchronizers from a lower level using - * {@link java.util.concurrent.atomic atomic} classes, your own custom - * {@link java.util.Queue} classes, and {@link LockSupport} blocking - * support. - * - * <h3>Usage Examples</h3> - * - * <p>Here is a non-reentrant mutual exclusion lock class that uses - * the value zero to represent the unlocked state, and one to - * represent the locked state. While a non-reentrant lock - * does not strictly require recording of the current owner - * thread, this class does so anyway to make usage easier to monitor. - * It also supports conditions and exposes - * one of the instrumentation methods: - * - * <pre> - * class Mutex implements Lock, java.io.Serializable { - * - * // Our internal helper class - * private static class Sync extends AbstractQueuedSynchronizer { - * // Report whether in locked state - * protected boolean isHeldExclusively() { - * return getState() == 1; - * } - * - * // Acquire the lock if state is zero - * public boolean tryAcquire(int acquires) { - * assert acquires == 1; // Otherwise unused - * if (compareAndSetState(0, 1)) { - * setExclusiveOwnerThread(Thread.currentThread()); - * return true; - * } - * return false; - * } - * - * // Release the lock by setting state to zero - * protected boolean tryRelease(int releases) { - * assert releases == 1; // Otherwise unused - * if (getState() == 0) throw new IllegalMonitorStateException(); - * setExclusiveOwnerThread(null); - * setState(0); - * return true; - * } - * - * // Provide a Condition - * Condition newCondition() { return new ConditionObject(); } - * - * // Deserialize properly - * private void readObject(ObjectInputStream s) - * throws IOException, ClassNotFoundException { - * s.defaultReadObject(); - * setState(0); // reset to unlocked state - * } - * } - * - * // The sync object does all the hard work. We just forward to it. - * private final Sync sync = new Sync(); - * - * public void lock() { sync.acquire(1); } - * public boolean tryLock() { return sync.tryAcquire(1); } - * public void unlock() { sync.release(1); } - * public Condition newCondition() { return sync.newCondition(); } - * public boolean isLocked() { return sync.isHeldExclusively(); } - * public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); } - * public void lockInterruptibly() throws InterruptedException { - * sync.acquireInterruptibly(1); - * } - * public boolean tryLock(long timeout, TimeUnit unit) - * throws InterruptedException { - * return sync.tryAcquireNanos(1, unit.toNanos(timeout)); - * } - * } - * </pre> - * - * <p>Here is a latch class that is like a {@link CountDownLatch} - * except that it only requires a single <tt>signal</tt> to - * fire. Because a latch is non-exclusive, it uses the <tt>shared</tt> - * acquire and release methods. - * - * <pre> - * class BooleanLatch { - * - * private static class Sync extends AbstractQueuedSynchronizer { - * boolean isSignalled() { return getState() != 0; } - * - * protected int tryAcquireShared(int ignore) { - * return isSignalled()? 1 : -1; - * } - * - * protected boolean tryReleaseShared(int ignore) { - * setState(1); - * return true; - * } - * } - * - * private final Sync sync = new Sync(); - * public boolean isSignalled() { return sync.isSignalled(); } - * public void signal() { sync.releaseShared(1); } - * public void await() throws InterruptedException { - * sync.acquireSharedInterruptibly(1); - * } - * } - * </pre> - * - * @since 1.5 - * @author Doug Lea - */ -public abstract class AbstractQueuedSynchronizer - extends AbstractOwnableSynchronizer - implements java.io.Serializable { - - private static final long serialVersionUID = 7373984972572414691L; - - /** - * Creates a new <tt>AbstractQueuedSynchronizer</tt> instance - * with initial synchronization state of zero. - */ - protected AbstractQueuedSynchronizer() { } - - /** - * Wait queue node class. - * - * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and - * Hagersten) lock queue. CLH locks are normally used for - * spinlocks. We instead use them for blocking synchronizers, but - * use the same basic tactic of holding some of the control - * information about a thread in the predecessor of its node. A - * "status" field in each node keeps track of whether a thread - * should block. A node is signalled when its predecessor - * releases. Each node of the queue otherwise serves as a - * specific-notification-style monitor holding a single waiting - * thread. The status field does NOT control whether threads are - * granted locks etc though. A thread may try to acquire if it is - * first in the queue. But being first does not guarantee success; - * it only gives the right to contend. So the currently released - * contender thread may need to rewait. - * - * <p>To enqueue into a CLH lock, you atomically splice it in as new - * tail. To dequeue, you just set the head field. - * <pre> - * +------+ prev +-----+ +-----+ - * head | | <---- | | <---- | | tail - * +------+ +-----+ +-----+ - * </pre> - * - * <p>Insertion into a CLH queue requires only a single atomic - * operation on "tail", so there is a simple atomic point of - * demarcation from unqueued to queued. Similarly, dequeing - * involves only updating the "head". However, it takes a bit - * more work for nodes to determine who their successors are, - * in part to deal with possible cancellation due to timeouts - * and interrupts. - * - * <p>The "prev" links (not used in original CLH locks), are mainly - * needed to handle cancellation. If a node is cancelled, its - * successor is (normally) relinked to a non-cancelled - * predecessor. For explanation of similar mechanics in the case - * of spin locks, see the papers by Scott and Scherer at - * http://www.cs.rochester.edu/u/scott/synchronization/ - * - * <p>We also use "next" links to implement blocking mechanics. - * The thread id for each node is kept in its own node, so a - * predecessor signals the next node to wake up by traversing - * next link to determine which thread it is. Determination of - * successor must avoid races with newly queued nodes to set - * the "next" fields of their predecessors. This is solved - * when necessary by checking backwards from the atomically - * updated "tail" when a node's successor appears to be null. - * (Or, said differently, the next-links are an optimization - * so that we don't usually need a backward scan.) - * - * <p>Cancellation introduces some conservatism to the basic - * algorithms. Since we must poll for cancellation of other - * nodes, we can miss noticing whether a cancelled node is - * ahead or behind us. This is dealt with by always unparking - * successors upon cancellation, allowing them to stabilize on - * a new predecessor. - * - * <p>CLH queues need a dummy header node to get started. But - * we don't create them on construction, because it would be wasted - * effort if there is never contention. Instead, the node - * is constructed and head and tail pointers are set upon first - * contention. - * - * <p>Threads waiting on Conditions use the same nodes, but - * use an additional link. Conditions only need to link nodes - * in simple (non-concurrent) linked queues because they are - * only accessed when exclusively held. Upon await, a node is - * inserted into a condition queue. Upon signal, the node is - * transferred to the main queue. A special value of status - * field is used to mark which queue a node is on. - * - * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill - * Scherer and Michael Scott, along with members of JSR-166 - * expert group, for helpful ideas, discussions, and critiques - * on the design of this class. - */ - static final class Node { - /** waitStatus value to indicate thread has cancelled */ - static final int CANCELLED = 1; - /** waitStatus value to indicate successor's thread needs unparking */ - static final int SIGNAL = -1; - /** waitStatus value to indicate thread is waiting on condition */ - static final int CONDITION = -2; - /** Marker to indicate a node is waiting in shared mode */ - static final Node SHARED = new Node(); - /** Marker to indicate a node is waiting in exclusive mode */ - static final Node EXCLUSIVE = null; - - /** - * Status field, taking on only the values: - * SIGNAL: The successor of this node is (or will soon be) - * blocked (via park), so the current node must - * unpark its successor when it releases or - * cancels. To avoid races, acquire methods must - * first indicate they need a signal, - * then retry the atomic acquire, and then, - * on failure, block. - * CANCELLED: This node is cancelled due to timeout or interrupt. - * Nodes never leave this state. In particular, - * a thread with cancelled node never again blocks. - * CONDITION: This node is currently on a condition queue. - * It will not be used as a sync queue node until - * transferred. (Use of this value here - * has nothing to do with the other uses - * of the field, but simplifies mechanics.) - * 0: None of the above - * - * The values are arranged numerically to simplify use. - * Non-negative values mean that a node doesn't need to - * signal. So, most code doesn't need to check for particular - * values, just for sign. - * - * The field is initialized to 0 for normal sync nodes, and - * CONDITION for condition nodes. It is modified only using - * CAS. - */ - volatile int waitStatus; - - /** - * Link to predecessor node that current node/thread relies on - * for checking waitStatus. Assigned during enqueing, and nulled - * out (for sake of GC) only upon dequeuing. Also, upon - * cancellation of a predecessor, we short-circuit while - * finding a non-cancelled one, which will always exist - * because the head node is never cancelled: A node becomes - * head only as a result of successful acquire. A - * cancelled thread never succeeds in acquiring, and a thread only - * cancels itself, not any other node. - */ - volatile Node prev; - - /** - * Link to the successor node that the current node/thread - * unparks upon release. Assigned once during enqueuing, and - * nulled out (for sake of GC) when no longer needed. Upon - * cancellation, we cannot adjust this field, but can notice - * status and bypass the node if cancelled. The enq operation - * does not assign next field of a predecessor until after - * attachment, so seeing a null next field does not - * necessarily mean that node is at end of queue. However, if - * a next field appears to be null, we can scan prev's from - * the tail to double-check. - */ - volatile Node next; - - /** - * The thread that enqueued this node. Initialized on - * construction and nulled out after use. - */ - volatile Thread thread; - - /** - * Link to next node waiting on condition, or the special - * value SHARED. Because condition queues are accessed only - * when holding in exclusive mode, we just need a simple - * linked queue to hold nodes while they are waiting on - * conditions. They are then transferred to the queue to - * re-acquire. And because conditions can only be exclusive, - * we save a field by using special value to indicate shared - * mode. - */ - Node nextWaiter; - - /** - * Returns true if node is waiting in shared mode - */ - final boolean isShared() { - return nextWaiter == SHARED; - } - - /** - * Returns previous node, or throws NullPointerException if - * null. Use when predecessor cannot be null. - * @return the predecessor of this node - */ - final Node predecessor() throws NullPointerException { - Node p = prev; - if (p == null) - throw new NullPointerException(); - else - return p; - } - - Node() { // Used to establish initial head or SHARED marker - } - - Node(Thread thread, Node mode) { // Used by addWaiter - this.nextWaiter = mode; - this.thread = thread; - } - - Node(Thread thread, int waitStatus) { // Used by Condition - this.waitStatus = waitStatus; - this.thread = thread; - } - } - - /** - * Head of the wait queue, lazily initialized. Except for - * initialization, it is modified only via method setHead. Note: - * If head exists, its waitStatus is guaranteed not to be - * CANCELLED. - */ - private transient volatile Node head; - - /** - * Tail of the wait queue, lazily initialized. Modified only via - * method enq to add new wait node. - */ - private transient volatile Node tail; - - /** - * The synchronization state. - */ - private volatile int state; - - /** - * Returns the current value of synchronization state. - * This operation has memory semantics of a <tt>volatile</tt> read. - * @return current state value - */ - protected final int getState() { - return state; - } - - /** - * Sets the value of synchronization state. - * This operation has memory semantics of a <tt>volatile</tt> write. - * @param newState the new state value - */ - protected final void setState(int newState) { - state = newState; - } - - /** - * Atomically sets synchronization state to the given updated - * value if the current state value equals the expected value. - * This operation has memory semantics of a <tt>volatile</tt> read - * and write. - * - * @param expect the expected value - * @param update the new value - * @return true if successful. False return indicates that the actual - * value was not equal to the expected value. - */ - protected final boolean compareAndSetState(int expect, int update) { - // See below for intrinsics setup to support this - return unsafe.compareAndSwapInt(this, stateOffset, expect, update); - } - - // Queuing utilities - - /** - * The number of nanoseconds for which it is faster to spin - * rather than to use timed park. A rough estimate suffices - * to improve responsiveness with very short timeouts. - */ - static final long spinForTimeoutThreshold = 1000L; - - /** - * Inserts node into queue, initializing if necessary. See picture above. - * @param node the node to insert - * @return node's predecessor - */ - private Node enq(final Node node) { - for (;;) { - Node t = tail; - if (t == null) { // Must initialize - Node h = new Node(); // Dummy header - h.next = node; - node.prev = h; - if (compareAndSetHead(h)) { - tail = node; - return h; - } - } - else { - node.prev = t; - if (compareAndSetTail(t, node)) { - t.next = node; - return t; - } - } - } - } - - /** - * Creates and enqueues node for given thread and mode. - * - * @param current the thread - * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared - * @return the new node - */ - private Node addWaiter(Node mode) { - Node node = new Node(Thread.currentThread(), mode); - // Try the fast path of enq; backup to full enq on failure - Node pred = tail; - if (pred != null) { - node.prev = pred; - if (compareAndSetTail(pred, node)) { - pred.next = node; - return node; - } - } - enq(node); - return node; - } - - /** - * Sets head of queue to be node, thus dequeuing. Called only by - * acquire methods. Also nulls out unused fields for sake of GC - * and to suppress unnecessary signals and traversals. - * - * @param node the node - */ - private void setHead(Node node) { - head = node; - node.thread = null; - node.prev = null; - } - - /** - * Wakes up node's successor, if one exists. - * - * @param node the node - */ - private void unparkSuccessor(Node node) { - /* - * Try to clear status in anticipation of signalling. It is - * OK if this fails or if status is changed by waiting thread. - */ - compareAndSetWaitStatus(node, Node.SIGNAL, 0); - - /* - * Thread to unpark is held in successor, which is normally - * just the next node. But if cancelled or apparently null, - * traverse backwards from tail to find the actual - * non-cancelled successor. - */ - Node s = node.next; - if (s == null || s.waitStatus > 0) { - s = null; - for (Node t = tail; t != null && t != node; t = t.prev) - if (t.waitStatus <= 0) - s = t; - } - if (s != null) - LockSupport.unpark(s.thread); - } - - /** - * Sets head of queue, and checks if successor may be waiting - * in shared mode, if so propagating if propagate > 0. - * - * @param pred the node holding waitStatus for node - * @param node the node - * @param propagate the return value from a tryAcquireShared - */ - private void setHeadAndPropagate(Node node, int propagate) { - setHead(node); - if (propagate > 0 && node.waitStatus != 0) { - /* - * Don't bother fully figuring out successor. If it - * looks null, call unparkSuccessor anyway to be safe. - */ - Node s = node.next; - if (s == null || s.isShared()) - unparkSuccessor(node); - } - } - - // Utilities for various versions of acquire - - /** - * Cancels an ongoing attempt to acquire. - * - * @param node the node - */ - private void cancelAcquire(Node node) { - if (node != null) { // Ignore if node doesn't exist - node.thread = null; - // Can use unconditional write instead of CAS here - node.waitStatus = Node.CANCELLED; - unparkSuccessor(node); - } - } - - /** - * Checks and updates status for a node that failed to acquire. - * Returns true if thread should block. This is the main signal - * control in all acquire loops. Requires that pred == node.prev - * - * @param pred node's predecessor holding status - * @param node the node - * @return {@code true} if thread should block - */ - private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { - int s = pred.waitStatus; - if (s < 0) - /* - * This node has already set status asking a release - * to signal it, so it can safely park - */ - return true; - if (s > 0) - /* - * Predecessor was cancelled. Move up to its predecessor - * and indicate retry. - */ - node.prev = pred.prev; - else - /* - * Indicate that we need a signal, but don't park yet. Caller - * will need to retry to make sure it cannot acquire before - * parking. - */ - compareAndSetWaitStatus(pred, 0, Node.SIGNAL); - return false; - } - - /** - * Convenience method to interrupt current thread. - */ - private static void selfInterrupt() { - Thread.currentThread().interrupt(); - } - - /** - * Convenience method to park and then check if interrupted - * - * @return {@code true} if interrupted - */ - private final boolean parkAndCheckInterrupt() { - LockSupport.park(this); - return Thread.interrupted(); - } - - /* - * Various flavors of acquire, varying in exclusive/shared and - * control modes. Each is mostly the same, but annoyingly - * different. Only a little bit of factoring is possible due to - * interactions of exception mechanics (including ensuring that we - * cancel if tryAcquire throws exception) and other control, at - * least not without hurting performance too much. - */ - - /** - * Acquires in exclusive uninterruptible mode for thread already in - * queue. Used by condition wait methods as well as acquire. - * - * @param node the node - * @param arg the acquire argument - * @return {@code true} if interrupted while waiting - */ - final boolean acquireQueued(final Node node, int arg) { - try { - boolean interrupted = false; - for (;;) { - final Node p = node.predecessor(); - if (p == head && tryAcquire(arg)) { - setHead(node); - p.next = null; // help GC - return interrupted; - } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - interrupted = true; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - } - - /** - * Acquires in exclusive interruptible mode. - * @param arg the acquire argument - */ - private void doAcquireInterruptibly(int arg) - throws InterruptedException { - final Node node = addWaiter(Node.EXCLUSIVE); - try { - for (;;) { - final Node p = node.predecessor(); - if (p == head && tryAcquire(arg)) { - setHead(node); - p.next = null; // help GC - return; - } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - break; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - // Arrive here only if interrupted - cancelAcquire(node); - throw new InterruptedException(); - } - - /** - * Acquires in exclusive timed mode. - * - * @param arg the acquire argument - * @param nanosTimeout max wait time - * @return {@code true} if acquired - */ - private boolean doAcquireNanos(int arg, long nanosTimeout) - throws InterruptedException { - long lastTime = System.nanoTime(); - final Node node = addWaiter(Node.EXCLUSIVE); - try { - for (;;) { - final Node p = node.predecessor(); - if (p == head && tryAcquire(arg)) { - setHead(node); - p.next = null; // help GC - return true; - } - if (nanosTimeout <= 0) { - cancelAcquire(node); - return false; - } - if (nanosTimeout > spinForTimeoutThreshold && - shouldParkAfterFailedAcquire(p, node)) - LockSupport.parkNanos(this, nanosTimeout); - long now = System.nanoTime(); - nanosTimeout -= now - lastTime; - lastTime = now; - if (Thread.interrupted()) - break; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - // Arrive here only if interrupted - cancelAcquire(node); - throw new InterruptedException(); - } - - /** - * Acquires in shared uninterruptible mode. - * @param arg the acquire argument - */ - private void doAcquireShared(int arg) { - final Node node = addWaiter(Node.SHARED); - try { - boolean interrupted = false; - for (;;) { - final Node p = node.predecessor(); - if (p == head) { - int r = tryAcquireShared(arg); - if (r >= 0) { - setHeadAndPropagate(node, r); - p.next = null; // help GC - if (interrupted) - selfInterrupt(); - return; - } - } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - interrupted = true; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - } - - /** - * Acquires in shared interruptible mode. - * @param arg the acquire argument - */ - private void doAcquireSharedInterruptibly(int arg) - throws InterruptedException { - final Node node = addWaiter(Node.SHARED); - try { - for (;;) { - final Node p = node.predecessor(); - if (p == head) { - int r = tryAcquireShared(arg); - if (r >= 0) { - setHeadAndPropagate(node, r); - p.next = null; // help GC - return; - } - } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - break; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - // Arrive here only if interrupted - cancelAcquire(node); - throw new InterruptedException(); - } - - /** - * Acquires in shared timed mode. - * - * @param arg the acquire argument - * @param nanosTimeout max wait time - * @return {@code true} if acquired - */ - private boolean doAcquireSharedNanos(int arg, long nanosTimeout) - throws InterruptedException { - - long lastTime = System.nanoTime(); - final Node node = addWaiter(Node.SHARED); - try { - for (;;) { - final Node p = node.predecessor(); - if (p == head) { - int r = tryAcquireShared(arg); - if (r >= 0) { - setHeadAndPropagate(node, r); - p.next = null; // help GC - return true; - } - } - if (nanosTimeout <= 0) { - cancelAcquire(node); - return false; - } - if (nanosTimeout > spinForTimeoutThreshold && - shouldParkAfterFailedAcquire(p, node)) - LockSupport.parkNanos(this, nanosTimeout); - long now = System.nanoTime(); - nanosTimeout -= now - lastTime; - lastTime = now; - if (Thread.interrupted()) - break; - } - } catch (RuntimeException ex) { - cancelAcquire(node); - throw ex; - } - // Arrive here only if interrupted - cancelAcquire(node); - throw new InterruptedException(); - } - - // Main exported methods - - /** - * Attempts to acquire in exclusive mode. This method should query - * if the state of the object permits it to be acquired in the - * exclusive mode, and if so to acquire it. - * - * <p>This method is always invoked by the thread performing - * acquire. If this method reports failure, the acquire method - * may queue the thread, if it is not already queued, until it is - * signalled by a release from some other thread. This can be used - * to implement method {@link Lock#tryLock()}. - * - * <p>The default - * implementation throws {@link UnsupportedOperationException}. - * - * @param arg the acquire argument. This value is always the one - * passed to an acquire method, or is the value saved on entry - * to a condition wait. The value is otherwise uninterpreted - * and can represent anything you like. - * @return {@code true} if successful. Upon success, this object has - * been acquired. - * @throws IllegalMonitorStateException if acquiring would place this - * synchronizer in an illegal state. This exception must be - * thrown in a consistent fashion for synchronization to work - * correctly. - * @throws UnsupportedOperationException if exclusive mode is not supported - */ - protected boolean tryAcquire(int arg) { - throw new UnsupportedOperationException(); - } - - /** - * Attempts to set the state to reflect a release in exclusive - * mode. - * - * <p>This method is always invoked by the thread performing release. - * - * <p>The default implementation throws - * {@link UnsupportedOperationException}. - * - * @param arg the release argument. This value is always the one - * passed to a release method, or the current state value upon - * entry to a condition wait. The value is otherwise - * uninterpreted and can represent anything you like. - * @return {@code true} if this object is now in a fully released - * state, so that any waiting threads may attempt to acquire; - * and {@code false} otherwise. - * @throws IllegalMonitorStateException if releasing would place this - * synchronizer in an illegal state. This exception must be - * thrown in a consistent fashion for synchronization to work - * correctly. - * @throws UnsupportedOperationException if exclusive mode is not supported - */ - protected boolean tryRelease(int arg) { - throw new UnsupportedOperationException(); - } - - /** - * Attempts to acquire in shared mode. This method should query if - * the state of the object permits it to be acquired in the shared - * mode, and if so to acquire it. - * - * <p>This method is always invoked by the thread performing - * acquire. If this method reports failure, the acquire method - * may queue the thread, if it is not already queued, until it is - * signalled by a release from some other thread. - * - * <p>The default implementation throws {@link - * UnsupportedOperationException}. - * - * @param arg the acquire argument. This value is always the one - * passed to an acquire method, or is the value saved on entry - * to a condition wait. The value is otherwise uninterpreted - * and can represent anything you like. - * @return a negative value on failure; zero if acquisition in shared - * mode succeeded but no subsequent shared-mode acquire can - * succeed; and a positive value if acquisition in shared - * mode succeeded and subsequent shared-mode acquires might - * also succeed, in which case a subsequent waiting thread - * must check availability. (Support for three different - * return values enables this method to be used in contexts - * where acquires only sometimes act exclusively.) Upon - * success, this object has been acquired. - * @throws IllegalMonitorStateException if acquiring would place this - * synchronizer in an illegal state. This exception must be - * thrown in a consistent fashion for synchronization to work - * correctly. - * @throws UnsupportedOperationException if shared mode is not supported - */ - protected int tryAcquireShared(int arg) { - throw new UnsupportedOperationException(); - } - - /** - * Attempts to set the state to reflect a release in shared mode. - * - * <p>This method is always invoked by the thread performing release. - * - * <p>The default implementation throws - * {@link UnsupportedOperationException}. - * - * @param arg the release argument. This value is always the one - * passed to a release method, or the current state value upon - * entry to a condition wait. The value is otherwise - * uninterpreted and can represent anything you like. - * @return {@code true} if this release of shared mode may permit a - * waiting acquire (shared or exclusive) to succeed; and - * {@code false} otherwise - * @throws IllegalMonitorStateException if releasing would place this - * synchronizer in an illegal state. This exception must be - * thrown in a consistent fashion for synchronization to work - * correctly. - * @throws UnsupportedOperationException if shared mode is not supported - */ - protected boolean tryReleaseShared(int arg) { - throw new UnsupportedOperationException(); - } - - /** - * Returns {@code true} if synchronization is held exclusively with - * respect to the current (calling) thread. This method is invoked - * upon each call to a non-waiting {@link ConditionObject} method. - * (Waiting methods instead invoke {@link #release}.) - * - * <p>The default implementation throws {@link - * UnsupportedOperationException}. This method is invoked - * internally only within {@link ConditionObject} methods, so need - * not be defined if conditions are not used. - * - * @return {@code true} if synchronization is held exclusively; - * {@code false} otherwise - * @throws UnsupportedOperationException if conditions are not supported - */ - protected boolean isHeldExclusively() { - throw new UnsupportedOperationException(); - } - - /** - * Acquires in exclusive mode, ignoring interrupts. Implemented - * by invoking at least once {@link #tryAcquire}, - * returning on success. Otherwise the thread is queued, possibly - * repeatedly blocking and unblocking, invoking {@link - * #tryAcquire} until success. This method can be used - * to implement method {@link Lock#lock}. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquire} but is otherwise uninterpreted and - * can represent anything you like. - */ - public final void acquire(int arg) { - if (!tryAcquire(arg) && - acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) - selfInterrupt(); - } - - /** - * Acquires in exclusive mode, aborting if interrupted. - * Implemented by first checking interrupt status, then invoking - * at least once {@link #tryAcquire}, returning on - * success. Otherwise the thread is queued, possibly repeatedly - * blocking and unblocking, invoking {@link #tryAcquire} - * until success or the thread is interrupted. This method can be - * used to implement method {@link Lock#lockInterruptibly}. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquire} but is otherwise uninterpreted and - * can represent anything you like. - * @throws InterruptedException if the current thread is interrupted - */ - public final void acquireInterruptibly(int arg) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - if (!tryAcquire(arg)) - doAcquireInterruptibly(arg); - } - - /** - * Attempts to acquire in exclusive mode, aborting if interrupted, - * and failing if the given timeout elapses. Implemented by first - * checking interrupt status, then invoking at least once {@link - * #tryAcquire}, returning on success. Otherwise, the thread is - * queued, possibly repeatedly blocking and unblocking, invoking - * {@link #tryAcquire} until success or the thread is interrupted - * or the timeout elapses. This method can be used to implement - * method {@link Lock#tryLock(long, TimeUnit)}. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquire} but is otherwise uninterpreted and - * can represent anything you like. - * @param nanosTimeout the maximum number of nanoseconds to wait - * @return {@code true} if acquired; {@code false} if timed out - * @throws InterruptedException if the current thread is interrupted - */ - public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - return tryAcquire(arg) || - doAcquireNanos(arg, nanosTimeout); - } - - /** - * Releases in exclusive mode. Implemented by unblocking one or - * more threads if {@link #tryRelease} returns true. - * This method can be used to implement method {@link Lock#unlock}. - * - * @param arg the release argument. This value is conveyed to - * {@link #tryRelease} but is otherwise uninterpreted and - * can represent anything you like. - * @return the value returned from {@link #tryRelease} - */ - public final boolean release(int arg) { - if (tryRelease(arg)) { - Node h = head; - if (h != null && h.waitStatus != 0) - unparkSuccessor(h); - return true; - } - return false; - } - - /** - * Acquires in shared mode, ignoring interrupts. Implemented by - * first invoking at least once {@link #tryAcquireShared}, - * returning on success. Otherwise the thread is queued, possibly - * repeatedly blocking and unblocking, invoking {@link - * #tryAcquireShared} until success. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquireShared} but is otherwise uninterpreted - * and can represent anything you like. - */ - public final void acquireShared(int arg) { - if (tryAcquireShared(arg) < 0) - doAcquireShared(arg); - } - - /** - * Acquires in shared mode, aborting if interrupted. Implemented - * by first checking interrupt status, then invoking at least once - * {@link #tryAcquireShared}, returning on success. Otherwise the - * thread is queued, possibly repeatedly blocking and unblocking, - * invoking {@link #tryAcquireShared} until success or the thread - * is interrupted. - * @param arg the acquire argument. - * This value is conveyed to {@link #tryAcquireShared} but is - * otherwise uninterpreted and can represent anything - * you like. - * @throws InterruptedException if the current thread is interrupted - */ - public final void acquireSharedInterruptibly(int arg) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - if (tryAcquireShared(arg) < 0) - doAcquireSharedInterruptibly(arg); - } - - /** - * Attempts to acquire in shared mode, aborting if interrupted, and - * failing if the given timeout elapses. Implemented by first - * checking interrupt status, then invoking at least once {@link - * #tryAcquireShared}, returning on success. Otherwise, the - * thread is queued, possibly repeatedly blocking and unblocking, - * invoking {@link #tryAcquireShared} until success or the thread - * is interrupted or the timeout elapses. - * - * @param arg the acquire argument. This value is conveyed to - * {@link #tryAcquireShared} but is otherwise uninterpreted - * and can represent anything you like. - * @param nanosTimeout the maximum number of nanoseconds to wait - * @return {@code true} if acquired; {@code false} if timed out - * @throws InterruptedException if the current thread is interrupted - */ - public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - return tryAcquireShared(arg) >= 0 || - doAcquireSharedNanos(arg, nanosTimeout); - } - - /** - * Releases in shared mode. Implemented by unblocking one or more - * threads if {@link #tryReleaseShared} returns true. - * - * @param arg the release argument. This value is conveyed to - * {@link #tryReleaseShared} but is otherwise uninterpreted - * and can represent anything you like. - * @return the value returned from {@link #tryReleaseShared} - */ - public final boolean releaseShared(int arg) { - if (tryReleaseShared(arg)) { - Node h = head; - if (h != null && h.waitStatus != 0) - unparkSuccessor(h); - return true; - } - return false; - } - - // Queue inspection methods - - /** - * Queries whether any threads are waiting to acquire. Note that - * because cancellations due to interrupts and timeouts may occur - * at any time, a {@code true} return does not guarantee that any - * other thread will ever acquire. - * - * <p>In this implementation, this operation returns in - * constant time. - * - * @return {@code true} if there may be other threads waiting to acquire - */ - public final boolean hasQueuedThreads() { - return head != tail; - } - - /** - * Queries whether any threads have ever contended to acquire this - * synchronizer; that is if an acquire method has ever blocked. - * - * <p>In this implementation, this operation returns in - * constant time. - * - * @return {@code true} if there has ever been contention - */ - public final boolean hasContended() { - return head != null; - } - - /** - * Returns the first (longest-waiting) thread in the queue, or - * {@code null} if no threads are currently queued. - * - * <p>In this implementation, this operation normally returns in - * constant time, but may iterate upon contention if other threads are - * concurrently modifying the queue. - * - * @return the first (longest-waiting) thread in the queue, or - * {@code null} if no threads are currently queued - */ - public final Thread getFirstQueuedThread() { - // handle only fast path, else relay - return (head == tail)? null : fullGetFirstQueuedThread(); - } - - /** - * Version of getFirstQueuedThread called when fastpath fails - */ - private Thread fullGetFirstQueuedThread() { - /* - * The first node is normally h.next. Try to get its - * thread field, ensuring consistent reads: If thread - * field is nulled out or s.prev is no longer head, then - * some other thread(s) concurrently performed setHead in - * between some of our reads. We try this twice before - * resorting to traversal. - */ - Node h, s; - Thread st; - if (((h = head) != null && (s = h.next) != null && - s.prev == head && (st = s.thread) != null) || - ((h = head) != null && (s = h.next) != null && - s.prev == head && (st = s.thread) != null)) - return st; - - /* - * Head's next field might not have been set yet, or may have - * been unset after setHead. So we must check to see if tail - * is actually first node. If not, we continue on, safely - * traversing from tail back to head to find first, - * guaranteeing termination. - */ - - Node t = tail; - Thread firstThread = null; - while (t != null && t != head) { - Thread tt = t.thread; - if (tt != null) - firstThread = tt; - t = t.prev; - } - return firstThread; - } - - /** - * Returns true if the given thread is currently queued. - * - * <p>This implementation traverses the queue to determine - * presence of the given thread. - * - * @param thread the thread - * @return {@code true} if the given thread is on the queue - * @throws NullPointerException if the thread is null - */ - public final boolean isQueued(Thread thread) { - if (thread == null) - throw new NullPointerException(); - for (Node p = tail; p != null; p = p.prev) - if (p.thread == thread) - return true; - return false; - } - - /** - * Return {@code true} if the apparent first queued thread, if one - * exists, is not waiting in exclusive mode. Used only as a heuristic - * in ReentrantReadWriteLock. - */ - final boolean apparentlyFirstQueuedIsExclusive() { - Node h, s; - return ((h = head) != null && (s = h.next) != null && - s.nextWaiter != Node.SHARED); - } - - /** - * Return {@code true} if the queue is empty or if the given thread - * is at the head of the queue. This is reliable only if - * <tt>current</tt> is actually Thread.currentThread() of caller. - */ - final boolean isFirst(Thread current) { - Node h, s; - return ((h = head) == null || - ((s = h.next) != null && s.thread == current) || - fullIsFirst(current)); - } - - final boolean fullIsFirst(Thread current) { - // same idea as fullGetFirstQueuedThread - Node h, s; - Thread firstThread = null; - if (((h = head) != null && (s = h.next) != null && - s.prev == head && (firstThread = s.thread) != null)) - return firstThread == current; - Node t = tail; - while (t != null && t != head) { - Thread tt = t.thread; - if (tt != null) - firstThread = tt; - t = t.prev; - } - return firstThread == current || firstThread == null; - } - - - // Instrumentation and monitoring methods - - /** - * Returns an estimate of the number of threads waiting to - * acquire. The value is only an estimate because the number of - * threads may change dynamically while this method traverses - * internal data structures. This method is designed for use in - * monitoring system state, not for synchronization - * control. - * - * @return the estimated number of threads waiting to acquire - */ - public final int getQueueLength() { - int n = 0; - for (Node p = tail; p != null; p = p.prev) { - if (p.thread != null) - ++n; - } - return n; - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire. Because the actual set of threads may change - * dynamically while constructing this result, the returned - * collection is only a best-effort estimate. The elements of the - * returned collection are in no particular order. This method is - * designed to facilitate construction of subclasses that provide - * more extensive monitoring facilities. - * - * @return the collection of threads - */ - public final Collection<Thread> getQueuedThreads() { - ArrayList<Thread> list = new ArrayList<Thread>(); - for (Node p = tail; p != null; p = p.prev) { - Thread t = p.thread; - if (t != null) - list.add(t); - } - return list; - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire in exclusive mode. This has the same properties - * as {@link #getQueuedThreads} except that it only returns - * those threads waiting due to an exclusive acquire. - * - * @return the collection of threads - */ - public final Collection<Thread> getExclusiveQueuedThreads() { - ArrayList<Thread> list = new ArrayList<Thread>(); - for (Node p = tail; p != null; p = p.prev) { - if (!p.isShared()) { - Thread t = p.thread; - if (t != null) - list.add(t); - } - } - return list; - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire in shared mode. This has the same properties - * as {@link #getQueuedThreads} except that it only returns - * those threads waiting due to a shared acquire. - * - * @return the collection of threads - */ - public final Collection<Thread> getSharedQueuedThreads() { - ArrayList<Thread> list = new ArrayList<Thread>(); - for (Node p = tail; p != null; p = p.prev) { - if (p.isShared()) { - Thread t = p.thread; - if (t != null) - list.add(t); - } - } - return list; - } - - /** - * Returns a string identifying this synchronizer, as well as its state. - * The state, in brackets, includes the String {@code "State ="} - * followed by the current value of {@link #getState}, and either - * {@code "nonempty"} or {@code "empty"} depending on whether the - * queue is empty. - * - * @return a string identifying this synchronizer, as well as its state - */ - public String toString() { - int s = getState(); - String q = hasQueuedThreads()? "non" : ""; - return super.toString() + - "[State = " + s + ", " + q + "empty queue]"; - } - - - // Internal support methods for Conditions - - /** - * Returns true if a node, always one that was initially placed on - * a condition queue, is now waiting to reacquire on sync queue. - * @param node the node - * @return true if is reacquiring - */ - final boolean isOnSyncQueue(Node node) { - if (node.waitStatus == Node.CONDITION || node.prev == null) - return false; - if (node.next != null) // If has successor, it must be on queue - return true; - /* - * node.prev can be non-null, but not yet on queue because - * the CAS to place it on queue can fail. So we have to - * traverse from tail to make sure it actually made it. It - * will always be near the tail in calls to this method, and - * unless the CAS failed (which is unlikely), it will be - * there, so we hardly ever traverse much. - */ - return findNodeFromTail(node); - } - - /** - * Returns true if node is on sync queue by searching backwards from tail. - * Called only when needed by isOnSyncQueue. - * @return true if present - */ - private boolean findNodeFromTail(Node node) { - Node t = tail; - for (;;) { - if (t == node) - return true; - if (t == null) - return false; - t = t.prev; - } - } - - /** - * Transfers a node from a condition queue onto sync queue. - * Returns true if successful. - * @param node the node - * @return true if successfully transferred (else the node was - * cancelled before signal). - */ - final boolean transferForSignal(Node node) { - /* - * If cannot change waitStatus, the node has been cancelled. - */ - if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) - return false; - - /* - * Splice onto queue and try to set waitStatus of predecessor to - * indicate that thread is (probably) waiting. If cancelled or - * attempt to set waitStatus fails, wake up to resync (in which - * case the waitStatus can be transiently and harmlessly wrong). - */ - Node p = enq(node); - int c = p.waitStatus; - if (c > 0 || !compareAndSetWaitStatus(p, c, Node.SIGNAL)) - LockSupport.unpark(node.thread); - return true; - } - - /** - * Transfers node, if necessary, to sync queue after a cancelled - * wait. Returns true if thread was cancelled before being - * signalled. - * @param current the waiting thread - * @param node its node - * @return true if cancelled before the node was signalled. - */ - final boolean transferAfterCancelledWait(Node node) { - if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { - enq(node); - return true; - } - /* - * If we lost out to a signal(), then we can't proceed - * until it finishes its enq(). Cancelling during an - * incomplete transfer is both rare and transient, so just - * spin. - */ - while (!isOnSyncQueue(node)) - Thread.yield(); - return false; - } - - /** - * Invokes release with current state value; returns saved state. - * Cancels node and throws exception on failure. - * @param node the condition node for this wait - * @return previous sync state - */ - final int fullyRelease(Node node) { - try { - int savedState = getState(); - if (release(savedState)) - return savedState; - } catch (RuntimeException ex) { - node.waitStatus = Node.CANCELLED; - throw ex; - } - // reach here if release fails - node.waitStatus = Node.CANCELLED; - throw new IllegalMonitorStateException(); - } - - // Instrumentation methods for conditions - - /** - * Queries whether the given ConditionObject - * uses this synchronizer as its lock. - * - * @param condition the condition - * @return <tt>true</tt> if owned - * @throws NullPointerException if the condition is null - */ - public final boolean owns(ConditionObject condition) { - if (condition == null) - throw new NullPointerException(); - return condition.isOwnedBy(this); - } - - /** - * Queries whether any threads are waiting on the given condition - * associated with this synchronizer. Note that because timeouts - * and interrupts may occur at any time, a <tt>true</tt> return - * does not guarantee that a future <tt>signal</tt> will awaken - * any threads. This method is designed primarily for use in - * monitoring of the system state. - * - * @param condition the condition - * @return <tt>true</tt> if there are any waiting threads - * @throws IllegalMonitorStateException if exclusive synchronization - * is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this synchronizer - * @throws NullPointerException if the condition is null - */ - public final boolean hasWaiters(ConditionObject condition) { - if (!owns(condition)) - throw new IllegalArgumentException("Not owner"); - return condition.hasWaiters(); - } - - /** - * Returns an estimate of the number of threads waiting on the - * given condition associated with this synchronizer. Note that - * because timeouts and interrupts may occur at any time, the - * estimate serves only as an upper bound on the actual number of - * waiters. This method is designed for use in monitoring of the - * system state, not for synchronization control. - * - * @param condition the condition - * @return the estimated number of waiting threads - * @throws IllegalMonitorStateException if exclusive synchronization - * is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this synchronizer - * @throws NullPointerException if the condition is null - */ - public final int getWaitQueueLength(ConditionObject condition) { - if (!owns(condition)) - throw new IllegalArgumentException("Not owner"); - return condition.getWaitQueueLength(); - } - - /** - * Returns a collection containing those threads that may be - * waiting on the given condition associated with this - * synchronizer. Because the actual set of threads may change - * dynamically while constructing this result, the returned - * collection is only a best-effort estimate. The elements of the - * returned collection are in no particular order. - * - * @param condition the condition - * @return the collection of threads - * @throws IllegalMonitorStateException if exclusive synchronization - * is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this synchronizer - * @throws NullPointerException if the condition is null - */ - public final Collection<Thread> getWaitingThreads(ConditionObject condition) { - if (!owns(condition)) - throw new IllegalArgumentException("Not owner"); - return condition.getWaitingThreads(); - } - - /** - * Condition implementation for a {@link - * AbstractQueuedSynchronizer} serving as the basis of a {@link - * Lock} implementation. - * - * <p>Method documentation for this class describes mechanics, - * not behavioral specifications from the point of view of Lock - * and Condition users. Exported versions of this class will in - * general need to be accompanied by documentation describing - * condition semantics that rely on those of the associated - * <tt>AbstractQueuedSynchronizer</tt>. - * - * <p>This class is Serializable, but all fields are transient, - * so deserialized conditions have no waiters. - */ - public class ConditionObject implements Condition, java.io.Serializable { - private static final long serialVersionUID = 1173984872572414699L; - /** First node of condition queue. */ - private transient Node firstWaiter; - /** Last node of condition queue. */ - private transient Node lastWaiter; - - /** - * Creates a new <tt>ConditionObject</tt> instance. - */ - public ConditionObject() { } - - // Internal methods - - /** - * Adds a new waiter to wait queue. - * @return its new wait node - */ - private Node addConditionWaiter() { - Node node = new Node(Thread.currentThread(), Node.CONDITION); - Node t = lastWaiter; - if (t == null) - firstWaiter = node; - else - t.nextWaiter = node; - lastWaiter = node; - return node; - } - - /** - * Removes and transfers nodes until hit non-cancelled one or - * null. Split out from signal in part to encourage compilers - * to inline the case of no waiters. - * @param first (non-null) the first node on condition queue - */ - private void doSignal(Node first) { - do { - if ( (firstWaiter = first.nextWaiter) == null) - lastWaiter = null; - first.nextWaiter = null; - } while (!transferForSignal(first) && - (first = firstWaiter) != null); - } - - /** - * Removes and transfers all nodes. - * @param first (non-null) the first node on condition queue - */ - private void doSignalAll(Node first) { - lastWaiter = firstWaiter = null; - do { - Node next = first.nextWaiter; - first.nextWaiter = null; - transferForSignal(first); - first = next; - } while (first != null); - } - - /** - * Returns true if given node is on this condition queue. - * Call only when holding lock. - */ - private boolean isOnConditionQueue(Node node) { - return node.next != null || node == lastWaiter; - } - - /** - * Unlinks a cancelled waiter node from condition queue. This - * is called when cancellation occurred during condition wait, - * not lock wait, and is called only after lock has been - * re-acquired by a cancelled waiter and the node is not known - * to already have been dequeued. It is needed to avoid - * garbage retention in the absence of signals. So even though - * it may require a full traversal, it comes into play only - * when timeouts or cancellations occur in the absence of - * signals. - */ - private void unlinkCancelledWaiter(Node node) { - Node t = firstWaiter; - Node trail = null; - while (t != null) { - if (t == node) { - Node next = t.nextWaiter; - if (trail == null) - firstWaiter = next; - else - trail.nextWaiter = next; - if (lastWaiter == node) - lastWaiter = trail; - break; - } - trail = t; - t = t.nextWaiter; - } - } - - // public methods - - /** - * Moves the longest-waiting thread, if one exists, from the - * wait queue for this condition to the wait queue for the - * owning lock. - * - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - public final void signal() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - Node first = firstWaiter; - if (first != null) - doSignal(first); - } - - /** - * Moves all threads from the wait queue for this condition to - * the wait queue for the owning lock. - * - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - public final void signalAll() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - Node first = firstWaiter; - if (first != null) - doSignalAll(first); - } - - /** - * Implements uninterruptible condition wait. - * <ol> - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * </ol> - */ - public final void awaitUninterruptibly() { - Node node = addConditionWaiter(); - int savedState = fullyRelease(node); - boolean interrupted = false; - while (!isOnSyncQueue(node)) { - LockSupport.park(this); - if (Thread.interrupted()) - interrupted = true; - } - if (acquireQueued(node, savedState) || interrupted) - selfInterrupt(); - } - - /* - * For interruptible waits, we need to track whether to throw - * InterruptedException, if interrupted while blocked on - * condition, versus reinterrupt current thread, if - * interrupted while blocked waiting to re-acquire. - */ - - /** Mode meaning to reinterrupt on exit from wait */ - private static final int REINTERRUPT = 1; - /** Mode meaning to throw InterruptedException on exit from wait */ - private static final int THROW_IE = -1; - - /** - * Checks for interrupt, returning THROW_IE if interrupted - * before signalled, REINTERRUPT if after signalled, or - * 0 if not interrupted. - */ - private int checkInterruptWhileWaiting(Node node) { - return (Thread.interrupted()) ? - ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) : - 0; - } - - /** - * Throws InterruptedException, reinterrupts current thread, or - * does nothing, depending on mode. - */ - private void reportInterruptAfterWait(int interruptMode) - throws InterruptedException { - if (interruptMode == THROW_IE) - throw new InterruptedException(); - else if (interruptMode == REINTERRUPT) - selfInterrupt(); - } - - /** - * Implements interruptible condition wait. - * <ol> - * <li> If current thread is interrupted, throw InterruptedException - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled or interrupted - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * <li> If interrupted while blocked in step 4, throw exception - * </ol> - */ - public final void await() throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - Node node = addConditionWaiter(); - int savedState = fullyRelease(node); - int interruptMode = 0; - while (!isOnSyncQueue(node)) { - LockSupport.park(this); - if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) - break; - } - if (acquireQueued(node, savedState) && interruptMode != THROW_IE) - interruptMode = REINTERRUPT; - if (isOnConditionQueue(node)) - unlinkCancelledWaiter(node); - if (interruptMode != 0) - reportInterruptAfterWait(interruptMode); - } - - /** - * Implements timed condition wait. - * <ol> - * <li> If current thread is interrupted, throw InterruptedException - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled, interrupted, or timed out - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * <li> If interrupted while blocked in step 4, throw InterruptedException - * </ol> - */ - public final long awaitNanos(long nanosTimeout) throws InterruptedException { - if (Thread.interrupted()) - throw new InterruptedException(); - Node node = addConditionWaiter(); - int savedState = fullyRelease(node); - long lastTime = System.nanoTime(); - int interruptMode = 0; - while (!isOnSyncQueue(node)) { - if (nanosTimeout <= 0L) { - transferAfterCancelledWait(node); - break; - } - LockSupport.parkNanos(this, nanosTimeout); - if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) - break; - - long now = System.nanoTime(); - nanosTimeout -= now - lastTime; - lastTime = now; - } - if (acquireQueued(node, savedState) && interruptMode != THROW_IE) - interruptMode = REINTERRUPT; - if (isOnConditionQueue(node)) - unlinkCancelledWaiter(node); - if (interruptMode != 0) - reportInterruptAfterWait(interruptMode); - return nanosTimeout - (System.nanoTime() - lastTime); - } - - /** - * Implements absolute timed condition wait. - * <ol> - * <li> If current thread is interrupted, throw InterruptedException - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled, interrupted, or timed out - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * <li> If interrupted while blocked in step 4, throw InterruptedException - * <li> If timed out while blocked in step 4, return false, else true - * </ol> - */ - public final boolean awaitUntil(Date deadline) throws InterruptedException { - if (deadline == null) - throw new NullPointerException(); - long abstime = deadline.getTime(); - if (Thread.interrupted()) - throw new InterruptedException(); - Node node = addConditionWaiter(); - int savedState = fullyRelease(node); - boolean timedout = false; - int interruptMode = 0; - while (!isOnSyncQueue(node)) { - if (System.currentTimeMillis() > abstime) { - timedout = transferAfterCancelledWait(node); - break; - } - LockSupport.parkUntil(this, abstime); - if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) - break; - } - if (acquireQueued(node, savedState) && interruptMode != THROW_IE) - interruptMode = REINTERRUPT; - if (isOnConditionQueue(node)) - unlinkCancelledWaiter(node); - if (interruptMode != 0) - reportInterruptAfterWait(interruptMode); - return !timedout; - } - - /** - * Implements timed condition wait. - * <ol> - * <li> If current thread is interrupted, throw InterruptedException - * <li> Save lock state returned by {@link #getState} - * <li> Invoke {@link #release} with - * saved state as argument, throwing - * IllegalMonitorStateException if it fails. - * <li> Block until signalled, interrupted, or timed out - * <li> Reacquire by invoking specialized version of - * {@link #acquire} with saved state as argument. - * <li> If interrupted while blocked in step 4, throw InterruptedException - * <li> If timed out while blocked in step 4, return false, else true - * </ol> - */ - public final boolean await(long time, TimeUnit unit) throws InterruptedException { - if (unit == null) - throw new NullPointerException(); - long nanosTimeout = unit.toNanos(time); - if (Thread.interrupted()) - throw new InterruptedException(); - Node node = addConditionWaiter(); - int savedState = fullyRelease(node); - long lastTime = System.nanoTime(); - boolean timedout = false; - int interruptMode = 0; - while (!isOnSyncQueue(node)) { - if (nanosTimeout <= 0L) { - timedout = transferAfterCancelledWait(node); - break; - } - LockSupport.parkNanos(this, nanosTimeout); - if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) - break; - long now = System.nanoTime(); - nanosTimeout -= now - lastTime; - lastTime = now; - } - if (acquireQueued(node, savedState) && interruptMode != THROW_IE) - interruptMode = REINTERRUPT; - if (isOnConditionQueue(node)) - unlinkCancelledWaiter(node); - if (interruptMode != 0) - reportInterruptAfterWait(interruptMode); - return !timedout; - } - - // support for instrumentation - - /** - * Returns true if this condition was created by the given - * synchronization object. - * - * @return {@code true} if owned - */ - final boolean isOwnedBy(AbstractQueuedSynchronizer sync) { - return sync == AbstractQueuedSynchronizer.this; - } - - /** - * Queries whether any threads are waiting on this condition. - * Implements {@link AbstractQueuedSynchronizer#hasWaiters}. - * - * @return {@code true} if there are any waiting threads - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - protected final boolean hasWaiters() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - for (Node w = firstWaiter; w != null; w = w.nextWaiter) { - if (w.waitStatus == Node.CONDITION) - return true; - } - return false; - } - - /** - * Returns an estimate of the number of threads waiting on - * this condition. - * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}. - * - * @return the estimated number of waiting threads - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - protected final int getWaitQueueLength() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - int n = 0; - for (Node w = firstWaiter; w != null; w = w.nextWaiter) { - if (w.waitStatus == Node.CONDITION) - ++n; - } - return n; - } - - /** - * Returns a collection containing those threads that may be - * waiting on this Condition. - * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}. - * - * @return the collection of threads - * @throws IllegalMonitorStateException if {@link #isHeldExclusively} - * returns {@code false} - */ - protected final Collection<Thread> getWaitingThreads() { - if (!isHeldExclusively()) - throw new IllegalMonitorStateException(); - ArrayList<Thread> list = new ArrayList<Thread>(); - for (Node w = firstWaiter; w != null; w = w.nextWaiter) { - if (w.waitStatus == Node.CONDITION) { - Thread t = w.thread; - if (t != null) - list.add(t); - } - } - return list; - } - } - - /** - * Setup to support compareAndSet. We need to natively implement - * this here: For the sake of permitting future enhancements, we - * cannot explicitly subclass AtomicInteger, which would be - * efficient and useful otherwise. So, as the lesser of evils, we - * natively implement using hotspot intrinsics API. And while we - * are at it, we do the same for other CASable fields (which could - * otherwise be done with atomic field updaters). - */ - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long stateOffset; - private static final long headOffset; - private static final long tailOffset; - private static final long waitStatusOffset; - - static { - try { - stateOffset = unsafe.objectFieldOffset - (AbstractQueuedSynchronizer.class.getDeclaredField("state")); - headOffset = unsafe.objectFieldOffset - (AbstractQueuedSynchronizer.class.getDeclaredField("head")); - tailOffset = unsafe.objectFieldOffset - (AbstractQueuedSynchronizer.class.getDeclaredField("tail")); - waitStatusOffset = unsafe.objectFieldOffset - (Node.class.getDeclaredField("waitStatus")); - - } catch (Exception ex) { throw new Error(ex); } - } - - /** - * CAS head field. Used only by enq - */ - private final boolean compareAndSetHead(Node update) { - return unsafe.compareAndSwapObject(this, headOffset, null, update); - } - - /** - * CAS tail field. Used only by enq - */ - private final boolean compareAndSetTail(Node expect, Node update) { - return unsafe.compareAndSwapObject(this, tailOffset, expect, update); - } - - /** - * CAS waitStatus field of a node. - */ - private final static boolean compareAndSetWaitStatus(Node node, - int expect, - int update) { - return unsafe.compareAndSwapInt(node, waitStatusOffset, - expect, update); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java deleted file mode 100644 index 5d24128..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; -import java.util.concurrent.*; -import java.util.Date; - -/** - * {@code Condition} factors out the {@code Object} monitor - * methods ({@link Object#wait() wait}, {@link Object#notify notify} - * and {@link Object#notifyAll notifyAll}) into distinct objects to - * give the effect of having multiple wait-sets per object, by - * combining them with the use of arbitrary {@link Lock} implementations. - * Where a {@code Lock} replaces the use of {@code synchronized} methods - * and statements, a {@code Condition} replaces the use of the Object - * monitor methods. - * - * <p>Conditions (also known as <em>condition queues</em> or - * <em>condition variables</em>) provide a means for one thread to - * suspend execution (to "wait") until notified by another - * thread that some state condition may now be true. Because access - * to this shared state information occurs in different threads, it - * must be protected, so a lock of some form is associated with the - * condition. The key property that waiting for a condition provides - * is that it <em>atomically</em> releases the associated lock and - * suspends the current thread, just like {@code Object.wait}. - * - * <p>A {@code Condition} instance is intrinsically bound to a lock. - * To obtain a {@code Condition} instance for a particular {@link Lock} - * instance use its {@link Lock#newCondition newCondition()} method. - * - * <p>As an example, suppose we have a bounded buffer which supports - * {@code put} and {@code take} methods. If a - * {@code take} is attempted on an empty buffer, then the thread will block - * until an item becomes available; if a {@code put} is attempted on a - * full buffer, then the thread will block until a space becomes available. - * We would like to keep waiting {@code put} threads and {@code take} - * threads in separate wait-sets so that we can use the optimization of - * only notifying a single thread at a time when items or spaces become - * available in the buffer. This can be achieved using two - * {@link Condition} instances. - * <pre> - * class BoundedBuffer { - * <b>final Lock lock = new ReentrantLock();</b> - * final Condition notFull = <b>lock.newCondition(); </b> - * final Condition notEmpty = <b>lock.newCondition(); </b> - * - * final Object[] items = new Object[100]; - * int putptr, takeptr, count; - * - * public void put(Object x) throws InterruptedException { - * <b>lock.lock(); - * try {</b> - * while (count == items.length) - * <b>notFull.await();</b> - * items[putptr] = x; - * if (++putptr == items.length) putptr = 0; - * ++count; - * <b>notEmpty.signal();</b> - * <b>} finally { - * lock.unlock(); - * }</b> - * } - * - * public Object take() throws InterruptedException { - * <b>lock.lock(); - * try {</b> - * while (count == 0) - * <b>notEmpty.await();</b> - * Object x = items[takeptr]; - * if (++takeptr == items.length) takeptr = 0; - * --count; - * <b>notFull.signal();</b> - * return x; - * <b>} finally { - * lock.unlock(); - * }</b> - * } - * } - * </pre> - * - * (The {@link java.util.concurrent.ArrayBlockingQueue} class provides - * this functionality, so there is no reason to implement this - * sample usage class.) - * - * <p>A {@code Condition} implementation can provide behavior and semantics - * that is - * different from that of the {@code Object} monitor methods, such as - * guaranteed ordering for notifications, or not requiring a lock to be held - * when performing notifications. - * If an implementation provides such specialized semantics then the - * implementation must document those semantics. - * - * <p>Note that {@code Condition} instances are just normal objects and can - * themselves be used as the target in a {@code synchronized} statement, - * and can have their own monitor {@link Object#wait wait} and - * {@link Object#notify notification} methods invoked. - * Acquiring the monitor lock of a {@code Condition} instance, or using its - * monitor methods, has no specified relationship with acquiring the - * {@link Lock} associated with that {@code Condition} or the use of its - * {@linkplain #await waiting} and {@linkplain #signal signalling} methods. - * It is recommended that to avoid confusion you never use {@code Condition} - * instances in this way, except perhaps within their own implementation. - * - * <p>Except where noted, passing a {@code null} value for any parameter - * will result in a {@link NullPointerException} being thrown. - * - * <h3>Implementation Considerations</h3> - * - * <p>When waiting upon a {@code Condition}, a "<em>spurious - * wakeup</em>" is permitted to occur, in - * general, as a concession to the underlying platform semantics. - * This has little practical impact on most application programs as a - * {@code Condition} should always be waited upon in a loop, testing - * the state predicate that is being waited for. An implementation is - * free to remove the possibility of spurious wakeups but it is - * recommended that applications programmers always assume that they can - * occur and so always wait in a loop. - * - * <p>The three forms of condition waiting - * (interruptible, non-interruptible, and timed) may differ in their ease of - * implementation on some platforms and in their performance characteristics. - * In particular, it may be difficult to provide these features and maintain - * specific semantics such as ordering guarantees. - * Further, the ability to interrupt the actual suspension of the thread may - * not always be feasible to implement on all platforms. - * - * <p>Consequently, an implementation is not required to define exactly the - * same guarantees or semantics for all three forms of waiting, nor is it - * required to support interruption of the actual suspension of the thread. - * - * <p>An implementation is required to - * clearly document the semantics and guarantees provided by each of the - * waiting methods, and when an implementation does support interruption of - * thread suspension then it must obey the interruption semantics as defined - * in this interface. - * - * <p>As interruption generally implies cancellation, and checks for - * interruption are often infrequent, an implementation can favor responding - * to an interrupt over normal method return. This is true even if it can be - * shown that the interrupt occurred after another action may have unblocked - * the thread. An implementation should document this behavior. - * - * @since 1.5 - * @author Doug Lea - */ -public interface Condition { - - /** - * Causes the current thread to wait until it is signalled or - * {@linkplain Thread#interrupt interrupted}. - * - * <p>The lock associated with this {@code Condition} is atomically - * released and the current thread becomes disabled for thread scheduling - * purposes and lies dormant until <em>one</em> of four things happens: - * <ul> - * <li>Some other thread invokes the {@link #signal} method for this - * {@code Condition} and the current thread happens to be chosen as the - * thread to be awakened; or - * <li>Some other thread invokes the {@link #signalAll} method for this - * {@code Condition}; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the - * current thread, and interruption of thread suspension is supported; or - * <li>A "<em>spurious wakeup</em>" occurs. - * </ul> - * - * <p>In all cases, before this method can return the current thread must - * re-acquire the lock associated with this condition. When the - * thread returns it is <em>guaranteed</em> to hold this lock. - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * and interruption of thread suspension is supported, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. It is not specified, in the first - * case, whether or not the test for interruption occurs before the lock - * is released. - * - * <p><b>Implementation Considerations</b> - * - * <p>The current thread is assumed to hold the lock associated with this - * {@code Condition} when this method is called. - * It is up to the implementation to determine if this is - * the case and if not, how to respond. Typically, an exception will be - * thrown (such as {@link IllegalMonitorStateException}) and the - * implementation must document that fact. - * - * <p>An implementation can favor responding to an interrupt over normal - * method return in response to a signal. In that case the implementation - * must ensure that the signal is redirected to another waiting thread, if - * there is one. - * - * @throws InterruptedException if the current thread is interrupted - * (and interruption of thread suspension is supported) - */ - void await() throws InterruptedException; - - /** - * Causes the current thread to wait until it is signalled. - * - * <p>The lock associated with this condition is atomically - * released and the current thread becomes disabled for thread scheduling - * purposes and lies dormant until <em>one</em> of three things happens: - * <ul> - * <li>Some other thread invokes the {@link #signal} method for this - * {@code Condition} and the current thread happens to be chosen as the - * thread to be awakened; or - * <li>Some other thread invokes the {@link #signalAll} method for this - * {@code Condition}; or - * <li>A "<em>spurious wakeup</em>" occurs. - * </ul> - * - * <p>In all cases, before this method can return the current thread must - * re-acquire the lock associated with this condition. When the - * thread returns it is <em>guaranteed</em> to hold this lock. - * - * <p>If the current thread's interrupted status is set when it enters - * this method, or it is {@linkplain Thread#interrupt interrupted} - * while waiting, it will continue to wait until signalled. When it finally - * returns from this method its interrupted status will still - * be set. - * - * <p><b>Implementation Considerations</b> - * - * <p>The current thread is assumed to hold the lock associated with this - * {@code Condition} when this method is called. - * It is up to the implementation to determine if this is - * the case and if not, how to respond. Typically, an exception will be - * thrown (such as {@link IllegalMonitorStateException}) and the - * implementation must document that fact. - */ - void awaitUninterruptibly(); - - /** - * Causes the current thread to wait until it is signalled or interrupted, - * or the specified waiting time elapses. - * - * <p>The lock associated with this condition is atomically - * released and the current thread becomes disabled for thread scheduling - * purposes and lies dormant until <em>one</em> of five things happens: - * <ul> - * <li>Some other thread invokes the {@link #signal} method for this - * {@code Condition} and the current thread happens to be chosen as the - * thread to be awakened; or - * <li>Some other thread invokes the {@link #signalAll} method for this - * {@code Condition}; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the - * current thread, and interruption of thread suspension is supported; or - * <li>The specified waiting time elapses; or - * <li>A "<em>spurious wakeup</em>" occurs. - * </ul> - * - * <p>In all cases, before this method can return the current thread must - * re-acquire the lock associated with this condition. When the - * thread returns it is <em>guaranteed</em> to hold this lock. - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * and interruption of thread suspension is supported, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. It is not specified, in the first - * case, whether or not the test for interruption occurs before the lock - * is released. - * - * <p>The method returns an estimate of the number of nanoseconds - * remaining to wait given the supplied {@code nanosTimeout} - * value upon return, or a value less than or equal to zero if it - * timed out. This value can be used to determine whether and how - * long to re-wait in cases where the wait returns but an awaited - * condition still does not hold. Typical uses of this method take - * the following form: - * - * <pre> - * synchronized boolean aMethod(long timeout, TimeUnit unit) { - * long nanosTimeout = unit.toNanos(timeout); - * while (!conditionBeingWaitedFor) { - * if (nanosTimeout > 0) - * nanosTimeout = theCondition.awaitNanos(nanosTimeout); - * else - * return false; - * } - * // ... - * } - * </pre> - * - * <p> Design note: This method requires a nanosecond argument so - * as to avoid truncation errors in reporting remaining times. - * Such precision loss would make it difficult for programmers to - * ensure that total waiting times are not systematically shorter - * than specified when re-waits occur. - * - * <p><b>Implementation Considerations</b> - * - * <p>The current thread is assumed to hold the lock associated with this - * {@code Condition} when this method is called. - * It is up to the implementation to determine if this is - * the case and if not, how to respond. Typically, an exception will be - * thrown (such as {@link IllegalMonitorStateException}) and the - * implementation must document that fact. - * - * <p>An implementation can favor responding to an interrupt over normal - * method return in response to a signal, or over indicating the elapse - * of the specified waiting time. In either case the implementation - * must ensure that the signal is redirected to another waiting thread, if - * there is one. - * - * @param nanosTimeout the maximum time to wait, in nanoseconds - * @return an estimate of the {@code nanosTimeout} value minus - * the time spent waiting upon return from this method. - * A positive value may be used as the argument to a - * subsequent call to this method to finish waiting out - * the desired time. A value less than or equal to zero - * indicates that no time remains. - * @throws InterruptedException if the current thread is interrupted - * (and interruption of thread suspension is supported) - */ - long awaitNanos(long nanosTimeout) throws InterruptedException; - - /** - * Causes the current thread to wait until it is signalled or interrupted, - * or the specified waiting time elapses. This method is behaviorally - * equivalent to:<br> - * <pre> - * awaitNanos(unit.toNanos(time)) > 0 - * </pre> - * @param time the maximum time to wait - * @param unit the time unit of the {@code time} argument - * @return {@code false} if the waiting time detectably elapsed - * before return from the method, else {@code true} - * @throws InterruptedException if the current thread is interrupted - * (and interruption of thread suspension is supported) - */ - boolean await(long time, TimeUnit unit) throws InterruptedException; - - /** - * Causes the current thread to wait until it is signalled or interrupted, - * or the specified deadline elapses. - * - * <p>The lock associated with this condition is atomically - * released and the current thread becomes disabled for thread scheduling - * purposes and lies dormant until <em>one</em> of five things happens: - * <ul> - * <li>Some other thread invokes the {@link #signal} method for this - * {@code Condition} and the current thread happens to be chosen as the - * thread to be awakened; or - * <li>Some other thread invokes the {@link #signalAll} method for this - * {@code Condition}; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the - * current thread, and interruption of thread suspension is supported; or - * <li>The specified deadline elapses; or - * <li>A "<em>spurious wakeup</em>" occurs. - * </ul> - * - * <p>In all cases, before this method can return the current thread must - * re-acquire the lock associated with this condition. When the - * thread returns it is <em>guaranteed</em> to hold this lock. - * - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while waiting - * and interruption of thread suspension is supported, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. It is not specified, in the first - * case, whether or not the test for interruption occurs before the lock - * is released. - * - * - * <p>The return value indicates whether the deadline has elapsed, - * which can be used as follows: - * <pre> - * synchronized boolean aMethod(Date deadline) { - * boolean stillWaiting = true; - * while (!conditionBeingWaitedFor) { - * if (stillWaiting) - * stillWaiting = theCondition.awaitUntil(deadline); - * else - * return false; - * } - * // ... - * } - * </pre> - * - * <p><b>Implementation Considerations</b> - * - * <p>The current thread is assumed to hold the lock associated with this - * {@code Condition} when this method is called. - * It is up to the implementation to determine if this is - * the case and if not, how to respond. Typically, an exception will be - * thrown (such as {@link IllegalMonitorStateException}) and the - * implementation must document that fact. - * - * <p>An implementation can favor responding to an interrupt over normal - * method return in response to a signal, or over indicating the passing - * of the specified deadline. In either case the implementation - * must ensure that the signal is redirected to another waiting thread, if - * there is one. - * - * @param deadline the absolute time to wait until - * @return {@code false} if the deadline has elapsed upon return, else - * {@code true} - * @throws InterruptedException if the current thread is interrupted - * (and interruption of thread suspension is supported) - */ - boolean awaitUntil(Date deadline) throws InterruptedException; - - /** - * Wakes up one waiting thread. - * - * <p>If any threads are waiting on this condition then one - * is selected for waking up. That thread must then re-acquire the - * lock before returning from {@code await}. - */ - void signal(); - - /** - * Wakes up all waiting threads. - * - * <p>If any threads are waiting on this condition then they are - * all woken up. Each thread must re-acquire the lock before it can - * return from {@code await}. - */ - void signalAll(); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java deleted file mode 100644 index 4b9abd6..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; -import java.util.concurrent.TimeUnit; - -/** - * {@code Lock} implementations provide more extensive locking - * operations than can be obtained using {@code synchronized} methods - * and statements. They allow more flexible structuring, may have - * quite different properties, and may support multiple associated - * {@link Condition} objects. - * - * <p>A lock is a tool for controlling access to a shared resource by - * multiple threads. Commonly, a lock provides exclusive access to a - * shared resource: only one thread at a time can acquire the lock and - * all access to the shared resource requires that the lock be - * acquired first. However, some locks may allow concurrent access to - * a shared resource, such as the read lock of a {@link ReadWriteLock}. - * - * <p>The use of {@code synchronized} methods or statements provides - * access to the implicit monitor lock associated with every object, but - * forces all lock acquisition and release to occur in a block-structured way: - * when multiple locks are acquired they must be released in the opposite - * order, and all locks must be released in the same lexical scope in which - * they were acquired. - * - * <p>While the scoping mechanism for {@code synchronized} methods - * and statements makes it much easier to program with monitor locks, - * and helps avoid many common programming errors involving locks, - * there are occasions where you need to work with locks in a more - * flexible way. For example, some algorithms for traversing - * concurrently accessed data structures require the use of - * "hand-over-hand" or "chain locking": you - * acquire the lock of node A, then node B, then release A and acquire - * C, then release B and acquire D and so on. Implementations of the - * {@code Lock} interface enable the use of such techniques by - * allowing a lock to be acquired and released in different scopes, - * and allowing multiple locks to be acquired and released in any - * order. - * - * <p>With this increased flexibility comes additional - * responsibility. The absence of block-structured locking removes the - * automatic release of locks that occurs with {@code synchronized} - * methods and statements. In most cases, the following idiom - * should be used: - * - * <pre><tt> Lock l = ...; - * l.lock(); - * try { - * // access the resource protected by this lock - * } finally { - * l.unlock(); - * } - * </tt></pre> - * - * When locking and unlocking occur in different scopes, care must be - * taken to ensure that all code that is executed while the lock is - * held is protected by try-finally or try-catch to ensure that the - * lock is released when necessary. - * - * <p>{@code Lock} implementations provide additional functionality - * over the use of {@code synchronized} methods and statements by - * providing a non-blocking attempt to acquire a lock ({@link - * #tryLock()}), an attempt to acquire the lock that can be - * interrupted ({@link #lockInterruptibly}, and an attempt to acquire - * the lock that can timeout ({@link #tryLock(long, TimeUnit)}). - * - * <p>A {@code Lock} class can also provide behavior and semantics - * that is quite different from that of the implicit monitor lock, - * such as guaranteed ordering, non-reentrant usage, or deadlock - * detection. If an implementation provides such specialized semantics - * then the implementation must document those semantics. - * - * <p>Note that {@code Lock} instances are just normal objects and can - * themselves be used as the target in a {@code synchronized} statement. - * Acquiring the - * monitor lock of a {@code Lock} instance has no specified relationship - * with invoking any of the {@link #lock} methods of that instance. - * It is recommended that to avoid confusion you never use {@code Lock} - * instances in this way, except within their own implementation. - * - * <p>Except where noted, passing a {@code null} value for any - * parameter will result in a {@link NullPointerException} being - * thrown. - * - * <h3>Memory Synchronization</h3> - * - * <p>All {@code Lock} implementations <em>must</em> enforce the same - * memory synchronization semantics as provided by the built-in monitor - * lock, as described in <a href="http://java.sun.com/docs/books/jls/"> - * The Java Language Specification, Third Edition (17.4 Memory Model)</a>: - * <ul> - * <li>A successful {@code lock} operation has the same memory - * synchronization effects as a successful <em>Lock</em> action. - * <li>A successful {@code unlock} operation has the same - * memory synchronization effects as a successful <em>Unlock</em> action. - * </ul> - * - * Unsuccessful locking and unlocking operations, and reentrant - * locking/unlocking operations, do not require any memory - * synchronization effects. - * - * <h3>Implementation Considerations</h3> - * - * <p> The three forms of lock acquisition (interruptible, - * non-interruptible, and timed) may differ in their performance - * characteristics, ordering guarantees, or other implementation - * qualities. Further, the ability to interrupt the <em>ongoing</em> - * acquisition of a lock may not be available in a given {@code Lock} - * class. Consequently, an implementation is not required to define - * exactly the same guarantees or semantics for all three forms of - * lock acquisition, nor is it required to support interruption of an - * ongoing lock acquisition. An implementation is required to clearly - * document the semantics and guarantees provided by each of the - * locking methods. It must also obey the interruption semantics as - * defined in this interface, to the extent that interruption of lock - * acquisition is supported: which is either totally, or only on - * method entry. - * - * <p>As interruption generally implies cancellation, and checks for - * interruption are often infrequent, an implementation can favor responding - * to an interrupt over normal method return. This is true even if it can be - * shown that the interrupt occurred after another action may have unblocked - * the thread. An implementation should document this behavior. - * - * @see ReentrantLock - * @see Condition - * @see ReadWriteLock - * - * @since 1.5 - * @author Doug Lea - */ -public interface Lock { - - /** - * Acquires the lock. - * - * <p>If the lock is not available then the current thread becomes - * disabled for thread scheduling purposes and lies dormant until the - * lock has been acquired. - * - * <p><b>Implementation Considerations</b> - * - * <p>A {@code Lock} implementation may be able to detect erroneous use - * of the lock, such as an invocation that would cause deadlock, and - * may throw an (unchecked) exception in such circumstances. The - * circumstances and the exception type must be documented by that - * {@code Lock} implementation. - */ - void lock(); - - /** - * Acquires the lock unless the current thread is - * {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires the lock if it is available and returns immediately. - * - * <p>If the lock is not available then the current thread becomes - * disabled for thread scheduling purposes and lies dormant until - * one of two things happens: - * - * <ul> - * <li>The lock is acquired by the current thread; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the - * current thread, and interruption of lock acquisition is supported. - * </ul> - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the - * lock, and interruption of lock acquisition is supported, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p><b>Implementation Considerations</b> - * - * <p>The ability to interrupt a lock acquisition in some - * implementations may not be possible, and if possible may be an - * expensive operation. The programmer should be aware that this - * may be the case. An implementation should document when this is - * the case. - * - * <p>An implementation can favor responding to an interrupt over - * normal method return. - * - * <p>A {@code Lock} implementation may be able to detect - * erroneous use of the lock, such as an invocation that would - * cause deadlock, and may throw an (unchecked) exception in such - * circumstances. The circumstances and the exception type must - * be documented by that {@code Lock} implementation. - * - * @throws InterruptedException if the current thread is - * interrupted while acquiring the lock (and interruption - * of lock acquisition is supported). - */ - void lockInterruptibly() throws InterruptedException; - - /** - * Acquires the lock only if it is free at the time of invocation. - * - * <p>Acquires the lock if it is available and returns immediately - * with the value {@code true}. - * If the lock is not available then this method will return - * immediately with the value {@code false}. - * - * <p>A typical usage idiom for this method would be: - * <pre> - * Lock lock = ...; - * if (lock.tryLock()) { - * try { - * // manipulate protected state - * } finally { - * lock.unlock(); - * } - * } else { - * // perform alternative actions - * } - * </pre> - * This usage ensures that the lock is unlocked if it was acquired, and - * doesn't try to unlock if the lock was not acquired. - * - * @return {@code true} if the lock was acquired and - * {@code false} otherwise - */ - boolean tryLock(); - - /** - * Acquires the lock if it is free within the given waiting time and the - * current thread has not been {@linkplain Thread#interrupt interrupted}. - * - * <p>If the lock is available this method returns immediately - * with the value {@code true}. - * If the lock is not available then - * the current thread becomes disabled for thread scheduling - * purposes and lies dormant until one of three things happens: - * <ul> - * <li>The lock is acquired by the current thread; or - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the - * current thread, and interruption of lock acquisition is supported; or - * <li>The specified waiting time elapses - * </ul> - * - * <p>If the lock is acquired then the value {@code true} is returned. - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@linkplain Thread#interrupt interrupted} while acquiring - * the lock, and interruption of lock acquisition is supported, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p>If the specified waiting time elapses then the value {@code false} - * is returned. - * If the time is - * less than or equal to zero, the method will not wait at all. - * - * <p><b>Implementation Considerations</b> - * - * <p>The ability to interrupt a lock acquisition in some implementations - * may not be possible, and if possible may - * be an expensive operation. - * The programmer should be aware that this may be the case. An - * implementation should document when this is the case. - * - * <p>An implementation can favor responding to an interrupt over normal - * method return, or reporting a timeout. - * - * <p>A {@code Lock} implementation may be able to detect - * erroneous use of the lock, such as an invocation that would cause - * deadlock, and may throw an (unchecked) exception in such circumstances. - * The circumstances and the exception type must be documented by that - * {@code Lock} implementation. - * - * @param time the maximum time to wait for the lock - * @param unit the time unit of the {@code time} argument - * @return {@code true} if the lock was acquired and {@code false} - * if the waiting time elapsed before the lock was acquired - * - * @throws InterruptedException if the current thread is interrupted - * while acquiring the lock (and interruption of lock - * acquisition is supported) - */ - boolean tryLock(long time, TimeUnit unit) throws InterruptedException; - - /** - * Releases the lock. - * - * <p><b>Implementation Considerations</b> - * - * <p>A {@code Lock} implementation will usually impose - * restrictions on which thread can release a lock (typically only the - * holder of the lock can release it) and may throw - * an (unchecked) exception if the restriction is violated. - * Any restrictions and the exception - * type must be documented by that {@code Lock} implementation. - */ - void unlock(); - - /** - * Returns a new {@link Condition} instance that is bound to this - * {@code Lock} instance. - * - * <p>Before waiting on the condition the lock must be held by the - * current thread. - * A call to {@link Condition#await()} will atomically release the lock - * before waiting and re-acquire the lock before the wait returns. - * - * <p><b>Implementation Considerations</b> - * - * <p>The exact operation of the {@link Condition} instance depends on - * the {@code Lock} implementation and must be documented by that - * implementation. - * - * @return A new {@link Condition} instance for this {@code Lock} instance - * @throws UnsupportedOperationException if this {@code Lock} - * implementation does not support conditions - */ - Condition newCondition(); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java deleted file mode 100644 index 28728ae..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; -import java.util.concurrent.*; -import sun.misc.Unsafe; - - -/** - * Basic thread blocking primitives for creating locks and other - * synchronization classes. - * - * <p>This class associates, with each thread that uses it, a permit - * (in the sense of the {@link java.util.concurrent.Semaphore - * Semaphore} class). A call to {@code park} will return immediately - * if the permit is available, consuming it in the process; otherwise - * it <em>may</em> block. A call to {@code unpark} makes the permit - * available, if it was not already available. (Unlike with Semaphores - * though, permits do not accumulate. There is at most one.) - * - * <p>Methods {@code park} and {@code unpark} provide efficient - * means of blocking and unblocking threads that do not encounter the - * problems that cause the deprecated methods {@code Thread.suspend} - * and {@code Thread.resume} to be unusable for such purposes: Races - * between one thread invoking {@code park} and another thread trying - * to {@code unpark} it will preserve liveness, due to the - * permit. Additionally, {@code park} will return if the caller's - * thread was interrupted, and timeout versions are supported. The - * {@code park} method may also return at any other time, for "no - * reason", so in general must be invoked within a loop that rechecks - * conditions upon return. In this sense {@code park} serves as an - * optimization of a "busy wait" that does not waste as much time - * spinning, but must be paired with an {@code unpark} to be - * effective. - * - * <p>The three forms of {@code park} each also support a - * {@code blocker} object parameter. This object is recorded while - * the thread is blocked to permit monitoring and diagnostic tools to - * identify the reasons that threads are blocked. (Such tools may - * access blockers using method {@link #getBlocker}.) The use of these - * forms rather than the original forms without this parameter is - * strongly encouraged. The normal argument to supply as a - * {@code blocker} within a lock implementation is {@code this}. - * - * <p>These methods are designed to be used as tools for creating - * higher-level synchronization utilities, and are not in themselves - * useful for most concurrency control applications. The {@code park} - * method is designed for use only in constructions of the form: - * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre> - * where neither {@code canProceed} nor any other actions prior to the - * call to {@code park} entail locking or blocking. Because only one - * permit is associated with each thread, any intermediary uses of - * {@code park} could interfere with its intended effects. - * - * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out - * non-reentrant lock class: - * <pre>{@code - * class FIFOMutex { - * private final AtomicBoolean locked = new AtomicBoolean(false); - * private final Queue<Thread> waiters - * = new ConcurrentLinkedQueue<Thread>(); - * - * public void lock() { - * boolean wasInterrupted = false; - * Thread current = Thread.currentThread(); - * waiters.add(current); - * - * // Block while not first in queue or cannot acquire lock - * while (waiters.peek() != current || - * !locked.compareAndSet(false, true)) { - * LockSupport.park(this); - * if (Thread.interrupted()) // ignore interrupts while waiting - * wasInterrupted = true; - * } - * - * waiters.remove(); - * if (wasInterrupted) // reassert interrupt status on exit - * current.interrupt(); - * } - * - * public void unlock() { - * locked.set(false); - * LockSupport.unpark(waiters.peek()); - * } - * }}</pre> - */ - -public class LockSupport { - private LockSupport() {} // Cannot be instantiated. - - // Hotspot implementation via intrinsics API - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long parkBlockerOffset; - - static { - try { - parkBlockerOffset = unsafe.objectFieldOffset - (java.lang.Thread.class.getDeclaredField("parkBlocker")); - } catch (Exception ex) { throw new Error(ex); } - } - - private static void setBlocker(Thread t, Object arg) { - // Even though volatile, hotspot doesn't need a write barrier here. - unsafe.putObject(t, parkBlockerOffset, arg); - } - - /** - * Makes available the permit for the given thread, if it - * was not already available. If the thread was blocked on - * {@code park} then it will unblock. Otherwise, its next call - * to {@code park} is guaranteed not to block. This operation - * is not guaranteed to have any effect at all if the given - * thread has not been started. - * - * @param thread the thread to unpark, or {@code null}, in which case - * this operation has no effect - */ - public static void unpark(Thread thread) { - if (thread != null) - unsafe.unpark(thread); - } - - /** - * Disables the current thread for thread scheduling purposes unless the - * permit is available. - * - * <p>If the permit is available then it is consumed and the call returns - * immediately; otherwise - * the current thread becomes disabled for thread scheduling - * purposes and lies dormant until one of three things happens: - * - * <ul> - * <li>Some other thread invokes {@link #unpark unpark} with the - * current thread as the target; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * - * <li>The call spuriously (that is, for no reason) returns. - * </ul> - * - * <p>This method does <em>not</em> report which of these caused the - * method to return. Callers should re-check the conditions which caused - * the thread to park in the first place. Callers may also determine, - * for example, the interrupt status of the thread upon return. - * - * @param blocker the synchronization object responsible for this - * thread parking - * @since 1.6 - */ - public static void park(Object blocker) { - Thread t = Thread.currentThread(); - setBlocker(t, blocker); - unsafe.park(false, 0L); - setBlocker(t, null); - } - - /** - * Disables the current thread for thread scheduling purposes, for up to - * the specified waiting time, unless the permit is available. - * - * <p>If the permit is available then it is consumed and the call - * returns immediately; otherwise the current thread becomes disabled - * for thread scheduling purposes and lies dormant until one of four - * things happens: - * - * <ul> - * <li>Some other thread invokes {@link #unpark unpark} with the - * current thread as the target; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current - * thread; or - * - * <li>The specified waiting time elapses; or - * - * <li>The call spuriously (that is, for no reason) returns. - * </ul> - * - * <p>This method does <em>not</em> report which of these caused the - * method to return. Callers should re-check the conditions which caused - * the thread to park in the first place. Callers may also determine, - * for example, the interrupt status of the thread, or the elapsed time - * upon return. - * - * @param blocker the synchronization object responsible for this - * thread parking - * @param nanos the maximum number of nanoseconds to wait - * @since 1.6 - */ - public static void parkNanos(Object blocker, long nanos) { - if (nanos > 0) { - Thread t = Thread.currentThread(); - setBlocker(t, blocker); - unsafe.park(false, nanos); - setBlocker(t, null); - } - } - - /** - * Disables the current thread for thread scheduling purposes, until - * the specified deadline, unless the permit is available. - * - * <p>If the permit is available then it is consumed and the call - * returns immediately; otherwise the current thread becomes disabled - * for thread scheduling purposes and lies dormant until one of four - * things happens: - * - * <ul> - * <li>Some other thread invokes {@link #unpark unpark} with the - * current thread as the target; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the - * current thread; or - * - * <li>The specified deadline passes; or - * - * <li>The call spuriously (that is, for no reason) returns. - * </ul> - * - * <p>This method does <em>not</em> report which of these caused the - * method to return. Callers should re-check the conditions which caused - * the thread to park in the first place. Callers may also determine, - * for example, the interrupt status of the thread, or the current time - * upon return. - * - * @param blocker the synchronization object responsible for this - * thread parking - * @param deadline the absolute time, in milliseconds from the Epoch, - * to wait until - * @since 1.6 - */ - public static void parkUntil(Object blocker, long deadline) { - Thread t = Thread.currentThread(); - setBlocker(t, blocker); - unsafe.park(true, deadline); - setBlocker(t, null); - } - - /** - * Returns the blocker object supplied to the most recent - * invocation of a park method that has not yet unblocked, or null - * if not blocked. The value returned is just a momentary - * snapshot -- the thread may have since unblocked or blocked on a - * different blocker object. - * - * @return the blocker - * @since 1.6 - */ - public static Object getBlocker(Thread t) { - return unsafe.getObjectVolatile(t, parkBlockerOffset); - } - - /** - * Disables the current thread for thread scheduling purposes unless the - * permit is available. - * - * <p>If the permit is available then it is consumed and the call - * returns immediately; otherwise the current thread becomes disabled - * for thread scheduling purposes and lies dormant until one of three - * things happens: - * - * <ul> - * - * <li>Some other thread invokes {@link #unpark unpark} with the - * current thread as the target; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * - * <li>The call spuriously (that is, for no reason) returns. - * </ul> - * - * <p>This method does <em>not</em> report which of these caused the - * method to return. Callers should re-check the conditions which caused - * the thread to park in the first place. Callers may also determine, - * for example, the interrupt status of the thread upon return. - */ - public static void park() { - unsafe.park(false, 0L); - } - - /** - * Disables the current thread for thread scheduling purposes, for up to - * the specified waiting time, unless the permit is available. - * - * <p>If the permit is available then it is consumed and the call - * returns immediately; otherwise the current thread becomes disabled - * for thread scheduling purposes and lies dormant until one of four - * things happens: - * - * <ul> - * <li>Some other thread invokes {@link #unpark unpark} with the - * current thread as the target; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * - * <li>The specified waiting time elapses; or - * - * <li>The call spuriously (that is, for no reason) returns. - * </ul> - * - * <p>This method does <em>not</em> report which of these caused the - * method to return. Callers should re-check the conditions which caused - * the thread to park in the first place. Callers may also determine, - * for example, the interrupt status of the thread, or the elapsed time - * upon return. - * - * @param nanos the maximum number of nanoseconds to wait - */ - public static void parkNanos(long nanos) { - if (nanos > 0) - unsafe.park(false, nanos); - } - - /** - * Disables the current thread for thread scheduling purposes, until - * the specified deadline, unless the permit is available. - * - * <p>If the permit is available then it is consumed and the call - * returns immediately; otherwise the current thread becomes disabled - * for thread scheduling purposes and lies dormant until one of four - * things happens: - * - * <ul> - * <li>Some other thread invokes {@link #unpark unpark} with the - * current thread as the target; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * - * <li>The specified deadline passes; or - * - * <li>The call spuriously (that is, for no reason) returns. - * </ul> - * - * <p>This method does <em>not</em> report which of these caused the - * method to return. Callers should re-check the conditions which caused - * the thread to park in the first place. Callers may also determine, - * for example, the interrupt status of the thread, or the current time - * upon return. - * - * @param deadline the absolute time, in milliseconds from the Epoch, - * to wait until - */ - public static void parkUntil(long deadline) { - unsafe.park(true, deadline); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java deleted file mode 100644 index 484f68d..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; - -/** - * A <tt>ReadWriteLock</tt> maintains a pair of associated {@link - * Lock locks}, one for read-only operations and one for writing. - * The {@link #readLock read lock} may be held simultaneously by - * multiple reader threads, so long as there are no writers. The - * {@link #writeLock write lock} is exclusive. - * - * <p>All <tt>ReadWriteLock</tt> implementations must guarantee that - * the memory synchronization effects of <tt>writeLock</tt> operations - * (as specified in the {@link Lock} interface) also hold with respect - * to the associated <tt>readLock</tt>. That is, a thread successfully - * acquiring the read lock will see all updates made upon previous - * release of the write lock. - * - * <p>A read-write lock allows for a greater level of concurrency in - * accessing shared data than that permitted by a mutual exclusion lock. - * It exploits the fact that while only a single thread at a time (a - * <em>writer</em> thread) can modify the shared data, in many cases any - * number of threads can concurrently read the data (hence <em>reader</em> - * threads). - * In theory, the increase in concurrency permitted by the use of a read-write - * lock will lead to performance improvements over the use of a mutual - * exclusion lock. In practice this increase in concurrency will only be fully - * realized on a multi-processor, and then only if the access patterns for - * the shared data are suitable. - * - * <p>Whether or not a read-write lock will improve performance over the use - * of a mutual exclusion lock depends on the frequency that the data is - * read compared to being modified, the duration of the read and write - * operations, and the contention for the data - that is, the number of - * threads that will try to read or write the data at the same time. - * For example, a collection that is initially populated with data and - * thereafter infrequently modified, while being frequently searched - * (such as a directory of some kind) is an ideal candidate for the use of - * a read-write lock. However, if updates become frequent then the data - * spends most of its time being exclusively locked and there is little, if any - * increase in concurrency. Further, if the read operations are too short - * the overhead of the read-write lock implementation (which is inherently - * more complex than a mutual exclusion lock) can dominate the execution - * cost, particularly as many read-write lock implementations still serialize - * all threads through a small section of code. Ultimately, only profiling - * and measurement will establish whether the use of a read-write lock is - * suitable for your application. - * - * - * <p>Although the basic operation of a read-write lock is straight-forward, - * there are many policy decisions that an implementation must make, which - * may affect the effectiveness of the read-write lock in a given application. - * Examples of these policies include: - * <ul> - * <li>Determining whether to grant the read lock or the write lock, when - * both readers and writers are waiting, at the time that a writer releases - * the write lock. Writer preference is common, as writes are expected to be - * short and infrequent. Reader preference is less common as it can lead to - * lengthy delays for a write if the readers are frequent and long-lived as - * expected. Fair, or "in-order" implementations are also possible. - * - * <li>Determining whether readers that request the read lock while a - * reader is active and a writer is waiting, are granted the read lock. - * Preference to the reader can delay the writer indefinitely, while - * preference to the writer can reduce the potential for concurrency. - * - * <li>Determining whether the locks are reentrant: can a thread with the - * write lock reacquire it? Can it acquire a read lock while holding the - * write lock? Is the read lock itself reentrant? - * - * <li>Can the write lock be downgraded to a read lock without allowing - * an intervening writer? Can a read lock be upgraded to a write lock, - * in preference to other waiting readers or writers? - * - * </ul> - * You should consider all of these things when evaluating the suitability - * of a given implementation for your application. - * - * @see ReentrantReadWriteLock - * @see Lock - * @see ReentrantLock - * - * @since 1.5 - * @author Doug Lea - */ -public interface ReadWriteLock { - /** - * Returns the lock used for reading. - * - * @return the lock used for reading. - */ - Lock readLock(); - - /** - * Returns the lock used for writing. - * - * @return the lock used for writing. - */ - Lock writeLock(); -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java deleted file mode 100644 index 4a2fc17..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java +++ /dev/null @@ -1,740 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - -/** - * A reentrant mutual exclusion {@link Lock} with the same basic - * behavior and semantics as the implicit monitor lock accessed using - * {@code synchronized} methods and statements, but with extended - * capabilities. - * - * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last - * successfully locking, but not yet unlocking it. A thread invoking - * {@code lock} will return, successfully acquiring the lock, when - * the lock is not owned by another thread. The method will return - * immediately if the current thread already owns the lock. This can - * be checked using methods {@link #isHeldByCurrentThread}, and {@link - * #getHoldCount}. - * - * <p>The constructor for this class accepts an optional - * <em>fairness</em> parameter. When set {@code true}, under - * contention, locks favor granting access to the longest-waiting - * thread. Otherwise this lock does not guarantee any particular - * access order. Programs using fair locks accessed by many threads - * may display lower overall throughput (i.e., are slower; often much - * slower) than those using the default setting, but have smaller - * variances in times to obtain locks and guarantee lack of - * starvation. Note however, that fairness of locks does not guarantee - * fairness of thread scheduling. Thus, one of many threads using a - * fair lock may obtain it multiple times in succession while other - * active threads are not progressing and not currently holding the - * lock. - * Also note that the untimed {@link #tryLock() tryLock} method does not - * honor the fairness setting. It will succeed if the lock - * is available even if other threads are waiting. - * - * <p>It is recommended practice to <em>always</em> immediately - * follow a call to {@code lock} with a {@code try} block, most - * typically in a before/after construction such as: - * - * <pre> - * class X { - * private final ReentrantLock lock = new ReentrantLock(); - * // ... - * - * public void m() { - * lock.lock(); // block until condition holds - * try { - * // ... method body - * } finally { - * lock.unlock() - * } - * } - * } - * </pre> - * - * <p>In addition to implementing the {@link Lock} interface, this - * class defines methods {@code isLocked} and - * {@code getLockQueueLength}, as well as some associated - * {@code protected} access methods that may be useful for - * instrumentation and monitoring. - * - * <p>Serialization of this class behaves in the same way as built-in - * locks: a deserialized lock is in the unlocked state, regardless of - * its state when serialized. - * - * <p>This lock supports a maximum of 2147483647 recursive locks by - * the same thread. Attempts to exceed this limit result in - * {@link Error} throws from locking methods. - * - * @since 1.5 - * @author Doug Lea - */ -public class ReentrantLock implements Lock, java.io.Serializable { - private static final long serialVersionUID = 7373984872572414699L; - /** Synchronizer providing all implementation mechanics */ - private final Sync sync; - - /** - * Base of synchronization control for this lock. Subclassed - * into fair and nonfair versions below. Uses AQS state to - * represent the number of holds on the lock. - */ - static abstract class Sync extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = -5179523762034025860L; - - /** - * Performs {@link Lock#lock}. The main reason for subclassing - * is to allow fast path for nonfair version. - */ - abstract void lock(); - - /** - * Performs non-fair tryLock. tryAcquire is - * implemented in subclasses, but both need nonfair - * try for trylock method. - */ - final boolean nonfairTryAcquire(int acquires) { - final Thread current = Thread.currentThread(); - int c = getState(); - if (c == 0) { - if (compareAndSetState(0, acquires)) { - setExclusiveOwnerThread(current); - return true; - } - } - else if (current == getExclusiveOwnerThread()) { - int nextc = c + acquires; - if (nextc < 0) // overflow - throw new Error("Maximum lock count exceeded"); - setState(nextc); - return true; - } - return false; - } - - protected final boolean tryRelease(int releases) { - int c = getState() - releases; - if (Thread.currentThread() != getExclusiveOwnerThread()) - throw new IllegalMonitorStateException(); - boolean free = false; - if (c == 0) { - free = true; - setExclusiveOwnerThread(null); - } - setState(c); - return free; - } - - protected final boolean isHeldExclusively() { - // While we must in general read state before owner, - // we don't need to do so to check if current thread is owner - return getExclusiveOwnerThread() == Thread.currentThread(); - } - - final ConditionObject newCondition() { - return new ConditionObject(); - } - - // Methods relayed from outer class - - final Thread getOwner() { - return getState() == 0 ? null : getExclusiveOwnerThread(); - } - - final int getHoldCount() { - return isHeldExclusively() ? getState() : 0; - } - - final boolean isLocked() { - return getState() != 0; - } - - /** - * Reconstitutes this lock instance from a stream. - * @param s the stream - */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); - setState(0); // reset to unlocked state - } - } - - /** - * Sync object for non-fair locks - */ - final static class NonfairSync extends Sync { - private static final long serialVersionUID = 7316153563782823691L; - - /** - * Performs lock. Try immediate barge, backing up to normal - * acquire on failure. - */ - final void lock() { - if (compareAndSetState(0, 1)) - setExclusiveOwnerThread(Thread.currentThread()); - else - acquire(1); - } - - protected final boolean tryAcquire(int acquires) { - return nonfairTryAcquire(acquires); - } - } - - /** - * Sync object for fair locks - */ - final static class FairSync extends Sync { - private static final long serialVersionUID = -3000897897090466540L; - - final void lock() { - acquire(1); - } - - /** - * Fair version of tryAcquire. Don't grant access unless - * recursive call or no waiters or is first. - */ - protected final boolean tryAcquire(int acquires) { - final Thread current = Thread.currentThread(); - int c = getState(); - if (c == 0) { - if (isFirst(current) && - compareAndSetState(0, acquires)) { - setExclusiveOwnerThread(current); - return true; - } - } - else if (current == getExclusiveOwnerThread()) { - int nextc = c + acquires; - if (nextc < 0) - throw new Error("Maximum lock count exceeded"); - setState(nextc); - return true; - } - return false; - } - } - - /** - * Creates an instance of {@code ReentrantLock}. - * This is equivalent to using {@code ReentrantLock(false)}. - */ - public ReentrantLock() { - sync = new NonfairSync(); - } - - /** - * Creates an instance of {@code ReentrantLock} with the - * given fairness policy. - * - * @param fair {@code true} if this lock should use a fair ordering policy - */ - public ReentrantLock(boolean fair) { - sync = (fair)? new FairSync() : new NonfairSync(); - } - - /** - * Acquires the lock. - * - * <p>Acquires the lock if it is not held by another thread and returns - * immediately, setting the lock hold count to one. - * - * <p>If the current thread already holds the lock then the hold - * count is incremented by one and the method returns immediately. - * - * <p>If the lock is held by another thread then the - * current thread becomes disabled for thread scheduling - * purposes and lies dormant until the lock has been acquired, - * at which time the lock hold count is set to one. - */ - public void lock() { - sync.lock(); - } - - /** - * Acquires the lock unless the current thread is - * {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires the lock if it is not held by another thread and returns - * immediately, setting the lock hold count to one. - * - * <p>If the current thread already holds this lock then the hold count - * is incremented by one and the method returns immediately. - * - * <p>If the lock is held by another thread then the - * current thread becomes disabled for thread scheduling - * purposes and lies dormant until one of two things happens: - * - * <ul> - * - * <li>The lock is acquired by the current thread; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} the - * current thread. - * - * </ul> - * - * <p>If the lock is acquired by the current thread then the lock hold - * count is set to one. - * - * <p>If the current thread: - * - * <ul> - * - * <li>has its interrupted status set on entry to this method; or - * - * <li>is {@linkplain Thread#interrupt interrupted} while acquiring - * the lock, - * - * </ul> - * - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p>In this implementation, as this method is an explicit - * interruption point, preference is given to responding to the - * interrupt over normal or reentrant acquisition of the lock. - * - * @throws InterruptedException if the current thread is interrupted - */ - public void lockInterruptibly() throws InterruptedException { - sync.acquireInterruptibly(1); - } - - /** - * Acquires the lock only if it is not held by another thread at the time - * of invocation. - * - * <p>Acquires the lock if it is not held by another thread and - * returns immediately with the value {@code true}, setting the - * lock hold count to one. Even when this lock has been set to use a - * fair ordering policy, a call to {@code tryLock()} <em>will</em> - * immediately acquire the lock if it is available, whether or not - * other threads are currently waiting for the lock. - * This "barging" behavior can be useful in certain - * circumstances, even though it breaks fairness. If you want to honor - * the fairness setting for this lock, then use - * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } - * which is almost equivalent (it also detects interruption). - * - * <p> If the current thread already holds this lock then the hold - * count is incremented by one and the method returns {@code true}. - * - * <p>If the lock is held by another thread then this method will return - * immediately with the value {@code false}. - * - * @return {@code true} if the lock was free and was acquired by the - * current thread, or the lock was already held by the current - * thread; and {@code false} otherwise - */ - public boolean tryLock() { - return sync.nonfairTryAcquire(1); - } - - /** - * Acquires the lock if it is not held by another thread within the given - * waiting time and the current thread has not been - * {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires the lock if it is not held by another thread and returns - * immediately with the value {@code true}, setting the lock hold count - * to one. If this lock has been set to use a fair ordering policy then - * an available lock <em>will not</em> be acquired if any other threads - * are waiting for the lock. This is in contrast to the {@link #tryLock()} - * method. If you want a timed {@code tryLock} that does permit barging on - * a fair lock then combine the timed and un-timed forms together: - * - * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } - * </pre> - * - * <p>If the current thread - * already holds this lock then the hold count is incremented by one and - * the method returns {@code true}. - * - * <p>If the lock is held by another thread then the - * current thread becomes disabled for thread scheduling - * purposes and lies dormant until one of three things happens: - * - * <ul> - * - * <li>The lock is acquired by the current thread; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * - * <li>The specified waiting time elapses - * - * </ul> - * - * <p>If the lock is acquired then the value {@code true} is returned and - * the lock hold count is set to one. - * - * <p>If the current thread: - * - * <ul> - * - * <li>has its interrupted status set on entry to this method; or - * - * <li>is {@linkplain Thread#interrupt interrupted} while - * acquiring the lock, - * - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. - * - * <p>If the specified waiting time elapses then the value {@code false} - * is returned. If the time is less than or equal to zero, the method - * will not wait at all. - * - * <p>In this implementation, as this method is an explicit - * interruption point, preference is given to responding to the - * interrupt over normal or reentrant acquisition of the lock, and - * over reporting the elapse of the waiting time. - * - * @param timeout the time to wait for the lock - * @param unit the time unit of the timeout argument - * @return {@code true} if the lock was free and was acquired by the - * current thread, or the lock was already held by the current - * thread; and {@code false} if the waiting time elapsed before - * the lock could be acquired - * @throws InterruptedException if the current thread is interrupted - * @throws NullPointerException if the time unit is null - * - */ - public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { - return sync.tryAcquireNanos(1, unit.toNanos(timeout)); - } - - /** - * Attempts to release this lock. - * - * <p>If the current thread is the holder of this lock then the hold - * count is decremented. If the hold count is now zero then the lock - * is released. If the current thread is not the holder of this - * lock then {@link IllegalMonitorStateException} is thrown. - * - * @throws IllegalMonitorStateException if the current thread does not - * hold this lock - */ - public void unlock() { - sync.release(1); - } - - /** - * Returns a {@link Condition} instance for use with this - * {@link Lock} instance. - * - * <p>The returned {@link Condition} instance supports the same - * usages as do the {@link Object} monitor methods ({@link - * Object#wait() wait}, {@link Object#notify notify}, and {@link - * Object#notifyAll notifyAll}) when used with the built-in - * monitor lock. - * - * <ul> - * - * <li>If this lock is not held when any of the {@link Condition} - * {@linkplain Condition#await() waiting} or {@linkplain - * Condition#signal signalling} methods are called, then an {@link - * IllegalMonitorStateException} is thrown. - * - * <li>When the condition {@linkplain Condition#await() waiting} - * methods are called the lock is released and, before they - * return, the lock is reacquired and the lock hold count restored - * to what it was when the method was called. - * - * <li>If a thread is {@linkplain Thread#interrupt interrupted} - * while waiting then the wait will terminate, an {@link - * InterruptedException} will be thrown, and the thread's - * interrupted status will be cleared. - * - * <li> Waiting threads are signalled in FIFO order. - * - * <li>The ordering of lock reacquisition for threads returning - * from waiting methods is the same as for threads initially - * acquiring the lock, which is in the default case not specified, - * but for <em>fair</em> locks favors those threads that have been - * waiting the longest. - * - * </ul> - * - * @return the Condition object - */ - public Condition newCondition() { - return sync.newCondition(); - } - - /** - * Queries the number of holds on this lock by the current thread. - * - * <p>A thread has a hold on a lock for each lock action that is not - * matched by an unlock action. - * - * <p>The hold count information is typically only used for testing and - * debugging purposes. For example, if a certain section of code should - * not be entered with the lock already held then we can assert that - * fact: - * - * <pre> - * class X { - * ReentrantLock lock = new ReentrantLock(); - * // ... - * public void m() { - * assert lock.getHoldCount() == 0; - * lock.lock(); - * try { - * // ... method body - * } finally { - * lock.unlock(); - * } - * } - * } - * </pre> - * - * @return the number of holds on this lock by the current thread, - * or zero if this lock is not held by the current thread - */ - public int getHoldCount() { - return sync.getHoldCount(); - } - - /** - * Queries if this lock is held by the current thread. - * - * <p>Analogous to the {@link Thread#holdsLock} method for built-in - * monitor locks, this method is typically used for debugging and - * testing. For example, a method that should only be called while - * a lock is held can assert that this is the case: - * - * <pre> - * class X { - * ReentrantLock lock = new ReentrantLock(); - * // ... - * - * public void m() { - * assert lock.isHeldByCurrentThread(); - * // ... method body - * } - * } - * </pre> - * - * <p>It can also be used to ensure that a reentrant lock is used - * in a non-reentrant manner, for example: - * - * <pre> - * class X { - * ReentrantLock lock = new ReentrantLock(); - * // ... - * - * public void m() { - * assert !lock.isHeldByCurrentThread(); - * lock.lock(); - * try { - * // ... method body - * } finally { - * lock.unlock(); - * } - * } - * } - * </pre> - * - * @return {@code true} if current thread holds this lock and - * {@code false} otherwise - */ - public boolean isHeldByCurrentThread() { - return sync.isHeldExclusively(); - } - - /** - * Queries if this lock is held by any thread. This method is - * designed for use in monitoring of the system state, - * not for synchronization control. - * - * @return {@code true} if any thread holds this lock and - * {@code false} otherwise - */ - public boolean isLocked() { - return sync.isLocked(); - } - - /** - * Returns {@code true} if this lock has fairness set true. - * - * @return {@code true} if this lock has fairness set true - */ - public final boolean isFair() { - return sync instanceof FairSync; - } - - /** - * Returns the thread that currently owns this lock, or - * {@code null} if not owned. When this method is called by a - * thread that is not the owner, the return value reflects a - * best-effort approximation of current lock status. For example, - * the owner may be momentarily {@code null} even if there are - * threads trying to acquire the lock but have not yet done so. - * This method is designed to facilitate construction of - * subclasses that provide more extensive lock monitoring - * facilities. - * - * @return the owner, or {@code null} if not owned - */ - protected Thread getOwner() { - return sync.getOwner(); - } - - /** - * Queries whether any threads are waiting to acquire this lock. Note that - * because cancellations may occur at any time, a {@code true} - * return does not guarantee that any other thread will ever - * acquire this lock. This method is designed primarily for use in - * monitoring of the system state. - * - * @return {@code true} if there may be other threads waiting to - * acquire the lock - */ - public final boolean hasQueuedThreads() { - return sync.hasQueuedThreads(); - } - - - /** - * Queries whether the given thread is waiting to acquire this - * lock. Note that because cancellations may occur at any time, a - * {@code true} return does not guarantee that this thread - * will ever acquire this lock. This method is designed primarily for use - * in monitoring of the system state. - * - * @param thread the thread - * @return {@code true} if the given thread is queued waiting for this lock - * @throws NullPointerException if the thread is null - */ - public final boolean hasQueuedThread(Thread thread) { - return sync.isQueued(thread); - } - - - /** - * Returns an estimate of the number of threads waiting to - * acquire this lock. The value is only an estimate because the number of - * threads may change dynamically while this method traverses - * internal data structures. This method is designed for use in - * monitoring of the system state, not for synchronization - * control. - * - * @return the estimated number of threads waiting for this lock - */ - public final int getQueueLength() { - return sync.getQueueLength(); - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire this lock. Because the actual set of threads may change - * dynamically while constructing this result, the returned - * collection is only a best-effort estimate. The elements of the - * returned collection are in no particular order. This method is - * designed to facilitate construction of subclasses that provide - * more extensive monitoring facilities. - * - * @return the collection of threads - */ - protected Collection<Thread> getQueuedThreads() { - return sync.getQueuedThreads(); - } - - /** - * Queries whether any threads are waiting on the given condition - * associated with this lock. Note that because timeouts and - * interrupts may occur at any time, a {@code true} return does - * not guarantee that a future {@code signal} will awaken any - * threads. This method is designed primarily for use in - * monitoring of the system state. - * - * @param condition the condition - * @return {@code true} if there are any waiting threads - * @throws IllegalMonitorStateException if this lock is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this lock - * @throws NullPointerException if the condition is null - */ - public boolean hasWaiters(Condition condition) { - if (condition == null) - throw new NullPointerException(); - if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) - throw new IllegalArgumentException("not owner"); - return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); - } - - /** - * Returns an estimate of the number of threads waiting on the - * given condition associated with this lock. Note that because - * timeouts and interrupts may occur at any time, the estimate - * serves only as an upper bound on the actual number of waiters. - * This method is designed for use in monitoring of the system - * state, not for synchronization control. - * - * @param condition the condition - * @return the estimated number of waiting threads - * @throws IllegalMonitorStateException if this lock is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this lock - * @throws NullPointerException if the condition is null - */ - public int getWaitQueueLength(Condition condition) { - if (condition == null) - throw new NullPointerException(); - if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) - throw new IllegalArgumentException("not owner"); - return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); - } - - /** - * Returns a collection containing those threads that may be - * waiting on the given condition associated with this lock. - * Because the actual set of threads may change dynamically while - * constructing this result, the returned collection is only a - * best-effort estimate. The elements of the returned collection - * are in no particular order. This method is designed to - * facilitate construction of subclasses that provide more - * extensive condition monitoring facilities. - * - * @param condition the condition - * @return the collection of threads - * @throws IllegalMonitorStateException if this lock is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this lock - * @throws NullPointerException if the condition is null - */ - protected Collection<Thread> getWaitingThreads(Condition condition) { - if (condition == null) - throw new NullPointerException(); - if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) - throw new IllegalArgumentException("not owner"); - return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition); - } - - /** - * Returns a string identifying this lock, as well as its lock state. - * The state, in brackets, includes either the String {@code "Unlocked"} - * or the String {@code "Locked by"} followed by the - * {@linkplain Thread#getName name} of the owning thread. - * - * @return a string identifying this lock, as well as its lock state - */ - public String toString() { - Thread o = sync.getOwner(); - return super.toString() + ((o == null) ? - "[Unlocked]" : - "[Locked by thread " + o.getName() + "]"); - } -} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java deleted file mode 100644 index a6eadff..0000000 --- a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ /dev/null @@ -1,1346 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - */ - -package java.util.concurrent.locks; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.*; - -/** - * An implementation of {@link ReadWriteLock} supporting similar - * semantics to {@link ReentrantLock}. - * <p>This class has the following properties: - * - * <ul> - * <li><b>Acquisition order</b> - * - * <p> This class does not impose a reader or writer preference - * ordering for lock access. However, it does support an optional - * <em>fairness</em> policy. - * - * <dl> - * <dt><b><i>Non-fair mode (default)</i></b> - * <dd>When constructed as non-fair (the default), the order of entry - * to the read and write lock is unspecified, subject to reentrancy - * constraints. A nonfair lock that is continously contended may - * indefinitely postpone one or more reader or writer threads, but - * will normally have higher throughput than a fair lock. - * <p> - * - * <dt><b><i>Fair mode</i></b> - * <dd> When constructed as fair, threads contend for entry using an - * approximately arrival-order policy. When the currently held lock - * is released either the longest-waiting single writer thread will - * be assigned the write lock, or if there is a group of reader threads - * waiting longer than all waiting writer threads, that group will be - * assigned the read lock. - * - * <p>A thread that tries to acquire a fair read lock (non-reentrantly) - * will block if either the write lock is held, or there is a waiting - * writer thread. The thread will not acquire the read lock until - * after the oldest currently waiting writer thread has acquired and - * released the write lock. Of course, if a waiting writer abandons - * its wait, leaving one or more reader threads as the longest waiters - * in the queue with the write lock free, then those readers will be - * assigned the read lock. - * - * <p>A thread that tries to acquire a fair write lock (non-reentrantly) - * will block unless both the read lock and write lock are free (which - * implies there are no waiting threads). (Note that the non-blocking - * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods - * do not honor this fair setting and will acquire the lock if it is - * possible, regardless of waiting threads.) - * <p> - * </dl> - * - * <li><b>Reentrancy</b> - * - * <p>This lock allows both readers and writers to reacquire read or - * write locks in the style of a {@link ReentrantLock}. Non-reentrant - * readers are not allowed until all write locks held by the writing - * thread have been released. - * - * <p>Additionally, a writer can acquire the read lock, but not - * vice-versa. Among other applications, reentrancy can be useful - * when write locks are held during calls or callbacks to methods that - * perform reads under read locks. If a reader tries to acquire the - * write lock it will never succeed. - * - * <li><b>Lock downgrading</b> - * <p>Reentrancy also allows downgrading from the write lock to a read lock, - * by acquiring the write lock, then the read lock and then releasing the - * write lock. However, upgrading from a read lock to the write lock is - * <b>not</b> possible. - * - * <li><b>Interruption of lock acquisition</b> - * <p>The read lock and write lock both support interruption during lock - * acquisition. - * - * <li><b>{@link Condition} support</b> - * <p>The write lock provides a {@link Condition} implementation that - * behaves in the same way, with respect to the write lock, as the - * {@link Condition} implementation provided by - * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}. - * This {@link Condition} can, of course, only be used with the write lock. - * - * <p>The read lock does not support a {@link Condition} and - * {@code readLock().newCondition()} throws - * {@code UnsupportedOperationException}. - * - * <li><b>Instrumentation</b> - * <p>This class supports methods to determine whether locks - * are held or contended. These methods are designed for monitoring - * system state, not for synchronization control. - * </ul> - * - * <p>Serialization of this class behaves in the same way as built-in - * locks: a deserialized lock is in the unlocked state, regardless of - * its state when serialized. - * - * <p><b>Sample usages</b>. Here is a code sketch showing how to exploit - * reentrancy to perform lock downgrading after updating a cache (exception - * handling is elided for simplicity): - * <pre> - * class CachedData { - * Object data; - * volatile boolean cacheValid; - * ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); - * - * void processCachedData() { - * rwl.readLock().lock(); - * if (!cacheValid) { - * // Must release read lock before acquiring write lock - * rwl.readLock().unlock(); - * rwl.writeLock().lock(); - * // Recheck state because another thread might have acquired - * // write lock and changed state before we did. - * if (!cacheValid) { - * data = ... - * cacheValid = true; - * } - * // Downgrade by acquiring read lock before releasing write lock - * rwl.readLock().lock(); - * rwl.writeLock().unlock(); // Unlock write, still hold read - * } - * - * use(data); - * rwl.readLock().unlock(); - * } - * } - * </pre> - * - * ReentrantReadWriteLocks can be used to improve concurrency in some - * uses of some kinds of Collections. This is typically worthwhile - * only when the collections are expected to be large, accessed by - * more reader threads than writer threads, and entail operations with - * overhead that outweighs synchronization overhead. For example, here - * is a class using a TreeMap that is expected to be large and - * concurrently accessed. - * - * <pre>{@code - * class RWDictionary { - * private final Map<String, Data> m = new TreeMap<String, Data>(); - * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); - * private final Lock r = rwl.readLock(); - * private final Lock w = rwl.writeLock(); - * - * public Data get(String key) { - * r.lock(); - * try { return m.get(key); } - * finally { r.unlock(); } - * } - * public String[] allKeys() { - * r.lock(); - * try { return m.keySet().toArray(); } - * finally { r.unlock(); } - * } - * public Data put(String key, Data value) { - * w.lock(); - * try { return m.put(key, value); } - * finally { w.unlock(); } - * } - * public void clear() { - * w.lock(); - * try { m.clear(); } - * finally { w.unlock(); } - * } - * }}</pre> - * - * <h3>Implementation Notes</h3> - * - * <p>This lock supports a maximum of 65535 recursive write locks - * and 65535 read locks. Attempts to exceed these limits result in - * {@link Error} throws from locking methods. - * - * @since 1.5 - * @author Doug Lea - * - */ -public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { - private static final long serialVersionUID = -6992448646407690164L; - /** Inner class providing readlock */ - private final ReentrantReadWriteLock.ReadLock readerLock; - /** Inner class providing writelock */ - private final ReentrantReadWriteLock.WriteLock writerLock; - /** Performs all synchronization mechanics */ - private final Sync sync; - - /** - * Creates a new {@code ReentrantReadWriteLock} with - * default (nonfair) ordering properties. - */ - public ReentrantReadWriteLock() { - this(false); - } - - /** - * Creates a new {@code ReentrantReadWriteLock} with - * the given fairness policy. - * - * @param fair {@code true} if this lock should use a fair ordering policy - */ - public ReentrantReadWriteLock(boolean fair) { - sync = (fair)? new FairSync() : new NonfairSync(); - readerLock = new ReadLock(this); - writerLock = new WriteLock(this); - } - - public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } - public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } - - /** - * Synchronization implementation for ReentrantReadWriteLock. - * Subclassed into fair and nonfair versions. - */ - static abstract class Sync extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = 6317671515068378041L; - - /* - * Read vs write count extraction constants and functions. - * Lock state is logically divided into two shorts: The lower - * one representing the exclusive (writer) lock hold count, - * and the upper the shared (reader) hold count. - */ - - static final int SHARED_SHIFT = 16; - static final int SHARED_UNIT = (1 << SHARED_SHIFT); - static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; - static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; - - /** Returns the number of shared holds represented in count */ - static int sharedCount(int c) { return c >>> SHARED_SHIFT; } - /** Returns the number of exclusive holds represented in count */ - static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; } - - /** - * A counter for per-thread read hold counts. - * Maintained as a ThreadLocal; cached in cachedHoldCounter - */ - static final class HoldCounter { - int count; - // Use id, not reference, to avoid garbage retention - final long tid = Thread.currentThread().getId(); - /** Decrement if positive; return previous value */ - int tryDecrement() { - int c = count; - if (c > 0) - count = c - 1; - return c; - } - } - - /** - * ThreadLocal subclass. Easiest to explicitly define for sake - * of deserialization mechanics. - */ - static final class ThreadLocalHoldCounter - extends ThreadLocal<HoldCounter> { - public HoldCounter initialValue() { - return new HoldCounter(); - } - } - - /** - * The number of read locks held by current thread. - * Initialized only in constructor and readObject. - */ - transient ThreadLocalHoldCounter readHolds; - - /** - * The hold count of the last thread to successfully acquire - * readLock. This saves ThreadLocal lookup in the common case - * where the next thread to release is the last one to - * acquire. This is non-volatile since it is just used - * as a heuristic, and would be great for threads to cache. - */ - transient HoldCounter cachedHoldCounter; - - Sync() { - readHolds = new ThreadLocalHoldCounter(); - setState(getState()); // ensures visibility of readHolds - } - - /* - * Acquires and releases use the same code for fair and - * nonfair locks, but differ in whether/how they allow barging - * when queues are non-empty. - */ - - /** - * Return true if a reader thread that is otherwise - * eligible for lock should block because of policy - * for overtaking other waiting threads. - */ - abstract boolean readerShouldBlock(Thread current); - - /** - * Return true if a writer thread that is otherwise - * eligible for lock should block because of policy - * for overtaking other waiting threads. - */ - abstract boolean writerShouldBlock(Thread current); - - /* - * Note that tryRelease and tryAcquire can be called by - * Conditions. So it is possible that their arguments contain - * both read and write holds that are all released during a - * condition wait and re-established in tryAcquire. - */ - - protected final boolean tryRelease(int releases) { - int nextc = getState() - releases; - if (Thread.currentThread() != getExclusiveOwnerThread()) - throw new IllegalMonitorStateException(); - if (exclusiveCount(nextc) == 0) { - setExclusiveOwnerThread(null); - setState(nextc); - return true; - } else { - setState(nextc); - return false; - } - } - - protected final boolean tryAcquire(int acquires) { - /* - * Walkthrough: - * 1. if read count nonzero or write count nonzero - * and owner is a different thread, fail. - * 2. If count would saturate, fail. (This can only - * happen if count is already nonzero.) - * 3. Otherwise, this thread is eligible for lock if - * it is either a reentrant acquire or - * queue policy allows it. If so, update state - * and set owner. - */ - Thread current = Thread.currentThread(); - int c = getState(); - int w = exclusiveCount(c); - if (c != 0) { - // (Note: if c != 0 and w == 0 then shared count != 0) - if (w == 0 || current != getExclusiveOwnerThread()) - return false; - if (w + exclusiveCount(acquires) > MAX_COUNT) - throw new Error("Maximum lock count exceeded"); - } - if ((w == 0 && writerShouldBlock(current)) || - !compareAndSetState(c, c + acquires)) - return false; - setExclusiveOwnerThread(current); - return true; - } - - protected final boolean tryReleaseShared(int unused) { - HoldCounter rh = cachedHoldCounter; - Thread current = Thread.currentThread(); - if (rh == null || rh.tid != current.getId()) - rh = readHolds.get(); - if (rh.tryDecrement() <= 0) - throw new IllegalMonitorStateException(); - for (;;) { - int c = getState(); - int nextc = c - SHARED_UNIT; - if (compareAndSetState(c, nextc)) - return nextc == 0; - } - } - - protected final int tryAcquireShared(int unused) { - /* - * Walkthrough: - * 1. If write lock held by another thread, fail - * 2. If count saturated, throw error - * 3. Otherwise, this thread is eligible for - * lock wrt state, so ask if it should block - * because of queue policy. If not, try - * to grant by CASing state and updating count. - * Note that step does not check for reentrant - * acquires, which is postponed to full version - * to avoid having to check hold count in - * the more typical non-reentrant case. - * 4. If step 3 fails either because thread - * apparently not eligible or CAS fails, - * chain to version with full retry loop. - */ - Thread current = Thread.currentThread(); - int c = getState(); - if (exclusiveCount(c) != 0 && - getExclusiveOwnerThread() != current) - return -1; - if (sharedCount(c) == MAX_COUNT) - throw new Error("Maximum lock count exceeded"); - if (!readerShouldBlock(current) && - compareAndSetState(c, c + SHARED_UNIT)) { - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - cachedHoldCounter = rh = readHolds.get(); - rh.count++; - return 1; - } - return fullTryAcquireShared(current); - } - - /** - * Full version of acquire for reads, that handles CAS misses - * and reentrant reads not dealt with in tryAcquireShared. - */ - final int fullTryAcquireShared(Thread current) { - /* - * This code is in part redundant with that in - * tryAcquireShared but is simpler overall by not - * complicating tryAcquireShared with interactions between - * retries and lazily reading hold counts. - */ - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - rh = readHolds.get(); - for (;;) { - int c = getState(); - int w = exclusiveCount(c); - if ((w != 0 && getExclusiveOwnerThread() != current) || - ((rh.count | w) == 0 && readerShouldBlock(current))) - return -1; - if (sharedCount(c) == MAX_COUNT) - throw new Error("Maximum lock count exceeded"); - if (compareAndSetState(c, c + SHARED_UNIT)) { - cachedHoldCounter = rh; // cache for release - rh.count++; - return 1; - } - } - } - - /** - * Performs tryLock for write, enabling barging in both modes. - * This is identical in effect to tryAcquire except for lack - * of calls to writerShouldBlock - */ - final boolean tryWriteLock() { - Thread current = Thread.currentThread(); - int c = getState(); - if (c != 0) { - int w = exclusiveCount(c); - if (w == 0 ||current != getExclusiveOwnerThread()) - return false; - if (w == MAX_COUNT) - throw new Error("Maximum lock count exceeded"); - } - if (!compareAndSetState(c, c + 1)) - return false; - setExclusiveOwnerThread(current); - return true; - } - - /** - * Performs tryLock for read, enabling barging in both modes. - * This is identical in effect to tryAcquireShared except for - * lack of calls to readerShouldBlock - */ - final boolean tryReadLock() { - Thread current = Thread.currentThread(); - for (;;) { - int c = getState(); - if (exclusiveCount(c) != 0 && - getExclusiveOwnerThread() != current) - return false; - if (sharedCount(c) == MAX_COUNT) - throw new Error("Maximum lock count exceeded"); - if (compareAndSetState(c, c + SHARED_UNIT)) { - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - cachedHoldCounter = rh = readHolds.get(); - rh.count++; - return true; - } - } - } - - protected final boolean isHeldExclusively() { - // While we must in general read state before owner, - // we don't need to do so to check if current thread is owner - return getExclusiveOwnerThread() == Thread.currentThread(); - } - - // Methods relayed to outer class - - final ConditionObject newCondition() { - return new ConditionObject(); - } - - final Thread getOwner() { - // Must read state before owner to ensure memory consistency - return ((exclusiveCount(getState()) == 0)? - null : - getExclusiveOwnerThread()); - } - - final int getReadLockCount() { - return sharedCount(getState()); - } - - final boolean isWriteLocked() { - return exclusiveCount(getState()) != 0; - } - - final int getWriteHoldCount() { - return isHeldExclusively() ? exclusiveCount(getState()) : 0; - } - - final int getReadHoldCount() { - return getReadLockCount() == 0? 0 : readHolds.get().count; - } - - /** - * Reconstitute this lock instance from a stream - * @param s the stream - */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); - readHolds = new ThreadLocalHoldCounter(); - setState(0); // reset to unlocked state - } - - final int getCount() { return getState(); } - } - - /** - * Nonfair version of Sync - */ - final static class NonfairSync extends Sync { - private static final long serialVersionUID = -8159625535654395037L; - final boolean writerShouldBlock(Thread current) { - return false; // writers can always barge - } - final boolean readerShouldBlock(Thread current) { - /* As a heuristic to avoid indefinite writer starvation, - * block if the thread that momentarily appears to be head - * of queue, if one exists, is a waiting writer. This is - * only a probablistic effect since a new reader will not - * block if there is a waiting writer behind other enabled - * readers that have not yet drained from the queue. - */ - return apparentlyFirstQueuedIsExclusive(); - } - } - - /** - * Fair version of Sync - */ - final static class FairSync extends Sync { - private static final long serialVersionUID = -2274990926593161451L; - final boolean writerShouldBlock(Thread current) { - // only proceed if queue is empty or current thread at head - return !isFirst(current); - } - final boolean readerShouldBlock(Thread current) { - // only proceed if queue is empty or current thread at head - return !isFirst(current); - } - } - - /** - * The lock returned by method {@link ReentrantReadWriteLock#readLock}. - */ - public static class ReadLock implements Lock, java.io.Serializable { - private static final long serialVersionUID = -5992448646407690164L; - private final Sync sync; - - /** - * Constructor for use by subclasses - * - * @param lock the outer lock object - * @throws NullPointerException if the lock is null - */ - protected ReadLock(ReentrantReadWriteLock lock) { - sync = lock.sync; - } - - /** - * Acquires the read lock. - * - * <p>Acquires the read lock if the write lock is not held by - * another thread and returns immediately. - * - * <p>If the write lock is held by another thread then - * the current thread becomes disabled for thread scheduling - * purposes and lies dormant until the read lock has been acquired. - */ - public void lock() { - sync.acquireShared(1); - } - - /** - * Acquires the read lock unless the current thread is - * {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires the read lock if the write lock is not held - * by another thread and returns immediately. - * - * <p>If the write lock is held by another thread then the - * current thread becomes disabled for thread scheduling - * purposes and lies dormant until one of two things happens: - * - * <ul> - * - * <li>The read lock is acquired by the current thread; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread. - * - * </ul> - * - * <p>If the current thread: - * - * <ul> - * - * <li>has its interrupted status set on entry to this method; or - * - * <li>is {@linkplain Thread#interrupt interrupted} while - * acquiring the read lock, - * - * </ul> - * - * then {@link InterruptedException} is thrown and the current - * thread's interrupted status is cleared. - * - * <p>In this implementation, as this method is an explicit - * interruption point, preference is given to responding to - * the interrupt over normal or reentrant acquisition of the - * lock. - * - * @throws InterruptedException if the current thread is interrupted - */ - public void lockInterruptibly() throws InterruptedException { - sync.acquireSharedInterruptibly(1); - } - - /** - * Acquires the read lock only if the write lock is not held by - * another thread at the time of invocation. - * - * <p>Acquires the read lock if the write lock is not held by - * another thread and returns immediately with the value - * {@code true}. Even when this lock has been set to use a - * fair ordering policy, a call to {@code tryLock()} - * <em>will</em> immediately acquire the read lock if it is - * available, whether or not other threads are currently - * waiting for the read lock. This "barging" behavior - * can be useful in certain circumstances, even though it - * breaks fairness. If you want to honor the fairness setting - * for this lock, then use {@link #tryLock(long, TimeUnit) - * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent - * (it also detects interruption). - * - * <p>If the write lock is held by another thread then - * this method will return immediately with the value - * {@code false}. - * - * @return {@code true} if the read lock was acquired - */ - public boolean tryLock() { - return sync.tryReadLock(); - } - - /** - * Acquires the read lock if the write lock is not held by - * another thread within the given waiting time and the - * current thread has not been {@linkplain Thread#interrupt - * interrupted}. - * - * <p>Acquires the read lock if the write lock is not held by - * another thread and returns immediately with the value - * {@code true}. If this lock has been set to use a fair - * ordering policy then an available lock <em>will not</em> be - * acquired if any other threads are waiting for the - * lock. This is in contrast to the {@link #tryLock()} - * method. If you want a timed {@code tryLock} that does - * permit barging on a fair lock then combine the timed and - * un-timed forms together: - * - * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } - * </pre> - * - * <p>If the write lock is held by another thread then the - * current thread becomes disabled for thread scheduling - * purposes and lies dormant until one of three things happens: - * - * <ul> - * - * <li>The read lock is acquired by the current thread; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * - * <li>The specified waiting time elapses. - * - * </ul> - * - * <p>If the read lock is acquired then the value {@code true} is - * returned. - * - * <p>If the current thread: - * - * <ul> - * - * <li>has its interrupted status set on entry to this method; or - * - * <li>is {@linkplain Thread#interrupt interrupted} while - * acquiring the read lock, - * - * </ul> then {@link InterruptedException} is thrown and the - * current thread's interrupted status is cleared. - * - * <p>If the specified waiting time elapses then the value - * {@code false} is returned. If the time is less than or - * equal to zero, the method will not wait at all. - * - * <p>In this implementation, as this method is an explicit - * interruption point, preference is given to responding to - * the interrupt over normal or reentrant acquisition of the - * lock, and over reporting the elapse of the waiting time. - * - * @param timeout the time to wait for the read lock - * @param unit the time unit of the timeout argument - * @return {@code true} if the read lock was acquired - * @throws InterruptedException if the current thread is interrupted - * @throws NullPointerException if the time unit is null - * - */ - public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { - return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); - } - - /** - * Attempts to release this lock. - * - * <p> If the number of readers is now zero then the lock - * is made available for write lock attempts. - */ - public void unlock() { - sync.releaseShared(1); - } - - /** - * Throws {@code UnsupportedOperationException} because - * {@code ReadLocks} do not support conditions. - * - * @throws UnsupportedOperationException always - */ - public Condition newCondition() { - throw new UnsupportedOperationException(); - } - - /** - * Returns a string identifying this lock, as well as its lock state. - * The state, in brackets, includes the String {@code "Read locks ="} - * followed by the number of held read locks. - * - * @return a string identifying this lock, as well as its lock state - */ - public String toString() { - int r = sync.getReadLockCount(); - return super.toString() + - "[Read locks = " + r + "]"; - } - } - - /** - * The lock returned by method {@link ReentrantReadWriteLock#writeLock}. - */ - public static class WriteLock implements Lock, java.io.Serializable { - private static final long serialVersionUID = -4992448646407690164L; - private final Sync sync; - - /** - * Constructor for use by subclasses - * - * @param lock the outer lock object - * @throws NullPointerException if the lock is null - */ - protected WriteLock(ReentrantReadWriteLock lock) { - sync = lock.sync; - } - - /** - * Acquires the write lock. - * - * <p>Acquires the write lock if neither the read nor write lock - * are held by another thread - * and returns immediately, setting the write lock hold count to - * one. - * - * <p>If the current thread already holds the write lock then the - * hold count is incremented by one and the method returns - * immediately. - * - * <p>If the lock is held by another thread then the current - * thread becomes disabled for thread scheduling purposes and - * lies dormant until the write lock has been acquired, at which - * time the write lock hold count is set to one. - */ - public void lock() { - sync.acquire(1); - } - - /** - * Acquires the write lock unless the current thread is - * {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires the write lock if neither the read nor write lock - * are held by another thread - * and returns immediately, setting the write lock hold count to - * one. - * - * <p>If the current thread already holds this lock then the - * hold count is incremented by one and the method returns - * immediately. - * - * <p>If the lock is held by another thread then the current - * thread becomes disabled for thread scheduling purposes and - * lies dormant until one of two things happens: - * - * <ul> - * - * <li>The write lock is acquired by the current thread; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread. - * - * </ul> - * - * <p>If the write lock is acquired by the current thread then the - * lock hold count is set to one. - * - * <p>If the current thread: - * - * <ul> - * - * <li>has its interrupted status set on entry to this method; - * or - * - * <li>is {@linkplain Thread#interrupt interrupted} while - * acquiring the write lock, - * - * </ul> - * - * then {@link InterruptedException} is thrown and the current - * thread's interrupted status is cleared. - * - * <p>In this implementation, as this method is an explicit - * interruption point, preference is given to responding to - * the interrupt over normal or reentrant acquisition of the - * lock. - * - * @throws InterruptedException if the current thread is interrupted - */ - public void lockInterruptibly() throws InterruptedException { - sync.acquireInterruptibly(1); - } - - /** - * Acquires the write lock only if it is not held by another thread - * at the time of invocation. - * - * <p>Acquires the write lock if neither the read nor write lock - * are held by another thread - * and returns immediately with the value {@code true}, - * setting the write lock hold count to one. Even when this lock has - * been set to use a fair ordering policy, a call to - * {@code tryLock()} <em>will</em> immediately acquire the - * lock if it is available, whether or not other threads are - * currently waiting for the write lock. This "barging" - * behavior can be useful in certain circumstances, even - * though it breaks fairness. If you want to honor the - * fairness setting for this lock, then use {@link - * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } - * which is almost equivalent (it also detects interruption). - * - * <p> If the current thread already holds this lock then the - * hold count is incremented by one and the method returns - * {@code true}. - * - * <p>If the lock is held by another thread then this method - * will return immediately with the value {@code false}. - * - * @return {@code true} if the lock was free and was acquired - * by the current thread, or the write lock was already held - * by the current thread; and {@code false} otherwise. - */ - public boolean tryLock( ) { - return sync.tryWriteLock(); - } - - /** - * Acquires the write lock if it is not held by another thread - * within the given waiting time and the current thread has - * not been {@linkplain Thread#interrupt interrupted}. - * - * <p>Acquires the write lock if neither the read nor write lock - * are held by another thread - * and returns immediately with the value {@code true}, - * setting the write lock hold count to one. If this lock has been - * set to use a fair ordering policy then an available lock - * <em>will not</em> be acquired if any other threads are - * waiting for the write lock. This is in contrast to the {@link - * #tryLock()} method. If you want a timed {@code tryLock} - * that does permit barging on a fair lock then combine the - * timed and un-timed forms together: - * - * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } - * </pre> - * - * <p>If the current thread already holds this lock then the - * hold count is incremented by one and the method returns - * {@code true}. - * - * <p>If the lock is held by another thread then the current - * thread becomes disabled for thread scheduling purposes and - * lies dormant until one of three things happens: - * - * <ul> - * - * <li>The write lock is acquired by the current thread; or - * - * <li>Some other thread {@linkplain Thread#interrupt interrupts} - * the current thread; or - * - * <li>The specified waiting time elapses - * - * </ul> - * - * <p>If the write lock is acquired then the value {@code true} is - * returned and the write lock hold count is set to one. - * - * <p>If the current thread: - * - * <ul> - * - * <li>has its interrupted status set on entry to this method; - * or - * - * <li>is {@linkplain Thread#interrupt interrupted} while - * acquiring the write lock, - * - * </ul> - * - * then {@link InterruptedException} is thrown and the current - * thread's interrupted status is cleared. - * - * <p>If the specified waiting time elapses then the value - * {@code false} is returned. If the time is less than or - * equal to zero, the method will not wait at all. - * - * <p>In this implementation, as this method is an explicit - * interruption point, preference is given to responding to - * the interrupt over normal or reentrant acquisition of the - * lock, and over reporting the elapse of the waiting time. - * - * @param timeout the time to wait for the write lock - * @param unit the time unit of the timeout argument - * - * @return {@code true} if the lock was free and was acquired - * by the current thread, or the write lock was already held by the - * current thread; and {@code false} if the waiting time - * elapsed before the lock could be acquired. - * - * @throws InterruptedException if the current thread is interrupted - * @throws NullPointerException if the time unit is null - * - */ - public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { - return sync.tryAcquireNanos(1, unit.toNanos(timeout)); - } - - /** - * Attempts to release this lock. - * - * <p>If the current thread is the holder of this lock then - * the hold count is decremented. If the hold count is now - * zero then the lock is released. If the current thread is - * not the holder of this lock then {@link - * IllegalMonitorStateException} is thrown. - * - * @throws IllegalMonitorStateException if the current thread does not - * hold this lock. - */ - public void unlock() { - sync.release(1); - } - - /** - * Returns a {@link Condition} instance for use with this - * {@link Lock} instance. - * <p>The returned {@link Condition} instance supports the same - * usages as do the {@link Object} monitor methods ({@link - * Object#wait() wait}, {@link Object#notify notify}, and {@link - * Object#notifyAll notifyAll}) when used with the built-in - * monitor lock. - * - * <ul> - * - * <li>If this write lock is not held when any {@link - * Condition} method is called then an {@link - * IllegalMonitorStateException} is thrown. (Read locks are - * held independently of write locks, so are not checked or - * affected. However it is essentially always an error to - * invoke a condition waiting method when the current thread - * has also acquired read locks, since other threads that - * could unblock it will not be able to acquire the write - * lock.) - * - * <li>When the condition {@linkplain Condition#await() waiting} - * methods are called the write lock is released and, before - * they return, the write lock is reacquired and the lock hold - * count restored to what it was when the method was called. - * - * <li>If a thread is {@linkplain Thread#interrupt interrupted} while - * waiting then the wait will terminate, an {@link - * InterruptedException} will be thrown, and the thread's - * interrupted status will be cleared. - * - * <li> Waiting threads are signalled in FIFO order. - * - * <li>The ordering of lock reacquisition for threads returning - * from waiting methods is the same as for threads initially - * acquiring the lock, which is in the default case not specified, - * but for <em>fair</em> locks favors those threads that have been - * waiting the longest. - * - * </ul> - * - * @return the Condition object - */ - public Condition newCondition() { - return sync.newCondition(); - } - - /** - * Returns a string identifying this lock, as well as its lock - * state. The state, in brackets includes either the String - * {@code "Unlocked"} or the String {@code "Locked by"} - * followed by the {@linkplain Thread#getName name} of the owning thread. - * - * @return a string identifying this lock, as well as its lock state - */ - public String toString() { - Thread o = sync.getOwner(); - return super.toString() + ((o == null) ? - "[Unlocked]" : - "[Locked by thread " + o.getName() + "]"); - } - - /** - * Queries if this write lock is held by the current thread. - * Identical in effect to {@link - * ReentrantReadWriteLock#isWriteLockedByCurrentThread}. - * - * @return {@code true} if the current thread holds this lock and - * {@code false} otherwise - * @since 1.6 - */ - public boolean isHeldByCurrentThread() { - return sync.isHeldExclusively(); - } - - /** - * Queries the number of holds on this write lock by the current - * thread. A thread has a hold on a lock for each lock action - * that is not matched by an unlock action. Identical in effect - * to {@link ReentrantReadWriteLock#getWriteHoldCount}. - * - * @return the number of holds on this lock by the current thread, - * or zero if this lock is not held by the current thread - * @since 1.6 - */ - public int getHoldCount() { - return sync.getWriteHoldCount(); - } - } - - // Instrumentation and status - - /** - * Returns {@code true} if this lock has fairness set true. - * - * @return {@code true} if this lock has fairness set true - */ - public final boolean isFair() { - return sync instanceof FairSync; - } - - /** - * Returns the thread that currently owns the write lock, or - * {@code null} if not owned. When this method is called by a - * thread that is not the owner, the return value reflects a - * best-effort approximation of current lock status. For example, - * the owner may be momentarily {@code null} even if there are - * threads trying to acquire the lock but have not yet done so. - * This method is designed to facilitate construction of - * subclasses that provide more extensive lock monitoring - * facilities. - * - * @return the owner, or {@code null} if not owned - */ - protected Thread getOwner() { - return sync.getOwner(); - } - - /** - * Queries the number of read locks held for this lock. This - * method is designed for use in monitoring system state, not for - * synchronization control. - * @return the number of read locks held. - */ - public int getReadLockCount() { - return sync.getReadLockCount(); - } - - /** - * Queries if the write lock is held by any thread. This method is - * designed for use in monitoring system state, not for - * synchronization control. - * - * @return {@code true} if any thread holds the write lock and - * {@code false} otherwise - */ - public boolean isWriteLocked() { - return sync.isWriteLocked(); - } - - /** - * Queries if the write lock is held by the current thread. - * - * @return {@code true} if the current thread holds the write lock and - * {@code false} otherwise - */ - public boolean isWriteLockedByCurrentThread() { - return sync.isHeldExclusively(); - } - - /** - * Queries the number of reentrant write holds on this lock by the - * current thread. A writer thread has a hold on a lock for - * each lock action that is not matched by an unlock action. - * - * @return the number of holds on the write lock by the current thread, - * or zero if the write lock is not held by the current thread - */ - public int getWriteHoldCount() { - return sync.getWriteHoldCount(); - } - - /** - * Queries the number of reentrant read holds on this lock by the - * current thread. A reader thread has a hold on a lock for - * each lock action that is not matched by an unlock action. - * - * @return the number of holds on the read lock by the current thread, - * or zero if the read lock is not held by the current thread - * @since 1.6 - */ - public int getReadHoldCount() { - return sync.getReadHoldCount(); - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire the write lock. Because the actual set of threads may - * change dynamically while constructing this result, the returned - * collection is only a best-effort estimate. The elements of the - * returned collection are in no particular order. This method is - * designed to facilitate construction of subclasses that provide - * more extensive lock monitoring facilities. - * - * @return the collection of threads - */ - protected Collection<Thread> getQueuedWriterThreads() { - return sync.getExclusiveQueuedThreads(); - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire the read lock. Because the actual set of threads may - * change dynamically while constructing this result, the returned - * collection is only a best-effort estimate. The elements of the - * returned collection are in no particular order. This method is - * designed to facilitate construction of subclasses that provide - * more extensive lock monitoring facilities. - * - * @return the collection of threads - */ - protected Collection<Thread> getQueuedReaderThreads() { - return sync.getSharedQueuedThreads(); - } - - /** - * Queries whether any threads are waiting to acquire the read or - * write lock. Note that because cancellations may occur at any - * time, a {@code true} return does not guarantee that any other - * thread will ever acquire a lock. This method is designed - * primarily for use in monitoring of the system state. - * - * @return {@code true} if there may be other threads waiting to - * acquire the lock - */ - public final boolean hasQueuedThreads() { - return sync.hasQueuedThreads(); - } - - /** - * Queries whether the given thread is waiting to acquire either - * the read or write lock. Note that because cancellations may - * occur at any time, a {@code true} return does not guarantee - * that this thread will ever acquire a lock. This method is - * designed primarily for use in monitoring of the system state. - * - * @param thread the thread - * @return {@code true} if the given thread is queued waiting for this lock - * @throws NullPointerException if the thread is null - */ - public final boolean hasQueuedThread(Thread thread) { - return sync.isQueued(thread); - } - - /** - * Returns an estimate of the number of threads waiting to acquire - * either the read or write lock. The value is only an estimate - * because the number of threads may change dynamically while this - * method traverses internal data structures. This method is - * designed for use in monitoring of the system state, not for - * synchronization control. - * - * @return the estimated number of threads waiting for this lock - */ - public final int getQueueLength() { - return sync.getQueueLength(); - } - - /** - * Returns a collection containing threads that may be waiting to - * acquire either the read or write lock. Because the actual set - * of threads may change dynamically while constructing this - * result, the returned collection is only a best-effort estimate. - * The elements of the returned collection are in no particular - * order. This method is designed to facilitate construction of - * subclasses that provide more extensive monitoring facilities. - * - * @return the collection of threads - */ - protected Collection<Thread> getQueuedThreads() { - return sync.getQueuedThreads(); - } - - /** - * Queries whether any threads are waiting on the given condition - * associated with the write lock. Note that because timeouts and - * interrupts may occur at any time, a {@code true} return does - * not guarantee that a future {@code signal} will awaken any - * threads. This method is designed primarily for use in - * monitoring of the system state. - * - * @param condition the condition - * @return {@code true} if there are any waiting threads - * @throws IllegalMonitorStateException if this lock is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this lock - * @throws NullPointerException if the condition is null - */ - public boolean hasWaiters(Condition condition) { - if (condition == null) - throw new NullPointerException(); - if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) - throw new IllegalArgumentException("not owner"); - return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); - } - - /** - * Returns an estimate of the number of threads waiting on the - * given condition associated with the write lock. Note that because - * timeouts and interrupts may occur at any time, the estimate - * serves only as an upper bound on the actual number of waiters. - * This method is designed for use in monitoring of the system - * state, not for synchronization control. - * - * @param condition the condition - * @return the estimated number of waiting threads - * @throws IllegalMonitorStateException if this lock is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this lock - * @throws NullPointerException if the condition is null - */ - public int getWaitQueueLength(Condition condition) { - if (condition == null) - throw new NullPointerException(); - if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) - throw new IllegalArgumentException("not owner"); - return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); - } - - /** - * Returns a collection containing those threads that may be - * waiting on the given condition associated with the write lock. - * Because the actual set of threads may change dynamically while - * constructing this result, the returned collection is only a - * best-effort estimate. The elements of the returned collection - * are in no particular order. This method is designed to - * facilitate construction of subclasses that provide more - * extensive condition monitoring facilities. - * - * @param condition the condition - * @return the collection of threads - * @throws IllegalMonitorStateException if this lock is not held - * @throws IllegalArgumentException if the given condition is - * not associated with this lock - * @throws NullPointerException if the condition is null - */ - protected Collection<Thread> getWaitingThreads(Condition condition) { - if (condition == null) - throw new NullPointerException(); - if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) - throw new IllegalArgumentException("not owner"); - return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition); - } - - /** - * Returns a string identifying this lock, as well as its lock state. - * The state, in brackets, includes the String {@code "Write locks ="} - * followed by the number of reentrantly held write locks, and the - * String {@code "Read locks ="} followed by the number of held - * read locks. - * - * @return a string identifying this lock, as well as its lock state - */ - public String toString() { - int c = sync.getCount(); - int w = Sync.exclusiveCount(c); - int r = Sync.sharedCount(c); - - return super.toString() + - "[Write locks = " + w + ", Read locks = " + r + "]"; - } - -} |