harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ndbe...@apache.org
Subject svn commit: r421111 [3/11] - in /incubator/harmony/enhanced/classlib/trunk/sandbox: ./ juc-proposal/ juc-proposal/concurrent/ juc-proposal/concurrent/.settings/ juc-proposal/concurrent/META-INF/ juc-proposal/concurrent/src/ juc-proposal/concurrent/src/...
Date Wed, 12 Jul 2006 04:12:08 GMT
Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,1178 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group.  Adapted and released, under explicit permission,
+ * from JDK ArrayList.java which carries the following copyright:
+ *
+ * Copyright 1997 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ */
+
+package java.util.concurrent;
+import java.util.*;
+
+/**
+ * A variant of {@link java.util.ArrayList} in which all mutative
+ * operations (add, set, and so on) are implemented by making a fresh
+ * copy of the underlying array.  
+ *
+ * <p> This is ordinarily too costly, but may be <em>more</em> efficient
+ * than alternatives when traversal operations vastly outnumber
+ * mutations, and is useful when you cannot or don't want to
+ * synchronize traversals, yet need to preclude interference among
+ * concurrent threads.  The "snapshot" style iterator method uses a
+ * reference to the state of the array at the point that the iterator
+ * was created. This array never changes during the lifetime of the
+ * iterator, so interference is impossible and the iterator is
+ * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
+ * The iterator will not reflect additions, removals, or changes to
+ * the list since the iterator was created.  Element-changing
+ * operations on iterators themselves (remove, set, and add) are not
+ * supported. These methods throw
+ * <tt>UnsupportedOperationException</tt>.
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../guide/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 CopyOnWriteArrayList<E>
+        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
+    private static final long serialVersionUID = 8673264195747942595L;
+
+    /**
+     * The held array. Directly accessed only within synchronized
+     *  methods
+     */
+    private volatile transient E[] array;
+
+    /**
+     * Accessor to the array intended to be called from
+     * within unsynchronized read-only methods
+     **/
+    private E[] array() { return array; }
+
+    /**
+     * Creates an empty list.
+     */
+    public CopyOnWriteArrayList() {
+        array = (E[]) new Object[0];
+    }
+
+    /**
+     * Creates a list containing the elements of the specified
+     * Collection, in the order they are returned by the Collection's
+     * iterator.
+     * @param c the collection of initially held elements
+     */
+    public CopyOnWriteArrayList(Collection<? extends E> c) {
+        array = (E[]) new Object[c.size()];
+        Iterator<? extends E> i = c.iterator();
+        int size = 0;
+        while (i.hasNext())
+            array[size++] = i.next();
+    }
+
+    /**
+     * Create a new CopyOnWriteArrayList holding a copy of given array.
+     *
+     * @param toCopyIn the array (a copy of this array is used as the
+     *        internal array)
+     **/
+    public CopyOnWriteArrayList(E[] toCopyIn) {
+        copyIn(toCopyIn, 0, toCopyIn.length);
+    }
+
+    /**
+     * Replace the held array with a copy of the <tt>n</tt> elements
+     * of the provided array, starting at position <tt>first</tt>.  To
+     * copy an entire array, call with arguments (array, 0,
+     * array.length).
+     * @param toCopyIn the array. A copy of the indicated elements of
+     * this array is used as the internal array.
+     * @param first The index of first position of the array to
+     * start copying from.
+     * @param n the number of elements to copy. This will be the new size of
+     * the list.
+     **/
+    private synchronized void copyIn(E[] toCopyIn, int first, int n) {
+        array  = (E[]) new Object[n];
+        System.arraycopy(toCopyIn, first, array, 0, n);
+    }
+
+    /**
+     * Returns the number of elements in this list.
+     *
+     * @return  the number of elements in this list.
+     */
+    public int size() {
+        return array().length;
+    }
+
+    /**
+     * Tests if this list has no elements.
+     *
+     * @return  <tt>true</tt> if this list has no elements;
+     *          <tt>false</tt> otherwise.
+     */
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    /**
+     * Returns <tt>true</tt> if this list contains the specified element.
+     *
+     * @param elem element whose presence in this List is to be tested.
+     * @return  <code>true</code> if the specified element is present;
+     *          <code>false</code> otherwise.
+     */
+    public boolean contains(Object elem) {
+        E[] elementData = array();
+        int len = elementData.length;
+        return indexOf(elem, elementData, len) >= 0;
+    }
+
+    /**
+     * Searches for the first occurrence of the given argument, testing 
+     * for equality using the <tt>equals</tt> method. 
+     *
+     * @param   elem   an object.
+     * @return  the index of the first occurrence of the argument in this
+     *          list; returns <tt>-1</tt> if the object is not found.
+     * @see     Object#equals(Object)
+     */
+    public int indexOf(Object elem) {
+        E[] elementData = array();
+        int len = elementData.length;
+        return indexOf(elem, elementData, len);
+    }
+
+    /**
+     * static version allows repeated call without needed
+     * to grab lock for array each time
+     **/
+    private static int indexOf(Object elem, Object[] elementData, int len) {
+        if (elem == null) {
+            for (int i = 0; i < len; i++)
+                if (elementData[i]==null)
+                    return i;
+        } else {
+            for (int i = 0; i < len; i++)
+                if (elem.equals(elementData[i]))
+                    return i;
+        }
+        return -1;
+    }
+
+    /**
+     * Searches for the first occurrence of the given argument, beginning
+     * the search at <tt>index</tt>, and testing for equality using
+     * the <tt>equals</tt> method.
+     *
+     * @param   elem    an object.
+     * @param   index   the index to start searching from.
+     * @return  the index of the first occurrence of the object argument in
+     *          this List at position <tt>index</tt> or later in the
+     *          List; returns <tt>-1</tt> if the object is not found.
+     * @see     Object#equals(Object)
+     */
+    public int indexOf(E elem, int index) {
+        E[] elementData = array();
+        int elementCount = elementData.length;
+
+        if (elem == null) {
+            for (int i = index ; i < elementCount ; i++)
+                if (elementData[i]==null)
+                    return i;
+        } else {
+            for (int i = index ; i < elementCount ; i++)
+                if (elem.equals(elementData[i]))
+                    return i;
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the index of the last occurrence of the specified object in
+     * this list.
+     *
+     * @param   elem   the desired element.
+     * @return  the index of the last occurrence of the specified object in
+     *          this list; returns -1 if the object is not found.
+     */
+    public int lastIndexOf(Object elem) {
+        E[] elementData = array();
+        int len = elementData.length;
+        return lastIndexOf(elem, elementData, len);
+    }
+
+    private static int lastIndexOf(Object elem, Object[] elementData, int len) {
+        if (elem == null) {
+            for (int i = len-1; i >= 0; i--)
+                if (elementData[i]==null)
+                    return i;
+        } else {
+            for (int i = len-1; i >= 0; i--)
+                if (elem.equals(elementData[i]))
+                    return i;
+        }
+        return -1;
+    }
+
+    /**
+     * Searches backwards for the specified object, starting from the
+     * specified index, and returns an index to it.
+     *
+     * @param  elem    the desired element.
+     * @param  index   the index to start searching from.
+     * @return the index of the last occurrence of the specified object in this
+     *          List at position less than index in the List;
+     *          -1 if the object is not found.
+     */
+    public int lastIndexOf(E elem, int index) {
+        // needed in order to compile on 1.2b3
+        E[] elementData = array();
+        if (elem == null) {
+            for (int i = index; i >= 0; i--)
+                if (elementData[i]==null)
+                    return i;
+        } else {
+            for (int i = index; i >= 0; i--)
+                if (elem.equals(elementData[i]))
+                    return i;
+        }
+        return -1;
+    }
+
+    /**
+     * Returns a shallow copy of this list.  (The elements themselves
+     * are not copied.)
+     *
+     * @return  a clone of this list.
+     */
+    public Object clone() {
+        try {
+            E[] elementData = array();
+            CopyOnWriteArrayList<E> v = (CopyOnWriteArrayList<E>)super.clone();
+            v.array = (E[]) new Object[elementData.length];
+            System.arraycopy(elementData, 0, v.array, 0, elementData.length);
+            return v;
+        } catch (CloneNotSupportedException e) {
+            // this shouldn't happen, since we are Cloneable
+            throw new InternalError();
+        }
+    }
+
+    /**
+     * Returns an array containing all of the elements in this list
+     * in the correct order.
+     * @return an array containing all of the elements in this list
+     *         in the correct order.
+     */
+    public Object[] toArray() {
+        Object[] elementData = array();
+        Object[] result = new Object[elementData.length];
+        System.arraycopy(elementData, 0, result, 0, elementData.length);
+        return result;
+    }
+
+    /**
+     * Returns an array containing all of the elements in this list in the
+     * correct order.  The runtime type of the returned array is that of the
+     * specified array.  If the list 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 list.
+     * <p>
+     * If the list fits in the specified array with room to spare
+     * (i.e., the array has more elements than the list),
+     * the element in the array immediately following the end of the
+     * collection is set to null.  This is useful in determining the length
+     * of the list <em>only</em> if the caller knows that the list
+     * does not contain any null elements.
+     *
+     * @param a the array into which the elements of the list 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 the elements of the list.
+     * @throws ArrayStoreException the runtime type of a is not a supertype
+     * of the runtime type of every element in this list.
+     */
+    public <T> T[] toArray(T a[]) {
+        E[] elementData = array();
+
+        if (a.length < elementData.length)
+            a = (T[])
+            java.lang.reflect.Array.newInstance(a.getClass().getComponentType(),
+            elementData.length);
+
+        System.arraycopy(elementData, 0, a, 0, elementData.length);
+
+        if (a.length > elementData.length)
+            a[elementData.length] = null;
+
+        return a;
+    }
+
+    // Positional Access Operations
+
+    /**
+     * Returns the element at the specified position in this list.
+     *
+     * @param  index index of element to return.
+     * @return the element at the specified position in this list.
+     * @throws    IndexOutOfBoundsException if index is out of range <tt>(index
+     *            &lt; 0 || index &gt;= size())</tt>.
+     */
+    public E get(int index) {
+        E[] elementData = array();
+        rangeCheck(index, elementData.length);
+        return elementData[index];
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with
+     * the specified element.
+     *
+     * @param index index of element to replace.
+     * @param element element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws    IndexOutOfBoundsException if index out of range
+     *            <tt>(index &lt; 0 || index &gt;= size())</tt>.
+     */
+    public synchronized E set(int index, E element) {
+        int len = array.length;
+        rangeCheck(index, len);
+        E oldValue = array[index];
+
+        boolean same = (oldValue == element ||
+        (element != null && element.equals(oldValue)));
+        if (!same) {
+            E[] newArray = (E[]) new Object[len];
+            System.arraycopy(array, 0, newArray, 0, len);
+            newArray[index] = element;
+            array = newArray;
+        }
+        return oldValue;
+    }
+
+    /**
+     * Appends the specified element to the end of this list.
+     *
+     * @param element element to be appended to this list.
+     * @return true (as per the general contract of Collection.add).
+     */
+    public synchronized boolean add(E element) {
+        int len = array.length;
+        E[] newArray = (E[]) new Object[len+1];
+        System.arraycopy(array, 0, newArray, 0, len);
+        newArray[len] = element;
+        array = newArray;
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this
+     * list. Shifts the element currently at that position (if any) and
+     * any subsequent elements to the right (adds one to their indices).
+     *
+     * @param index index at which the specified element is to be inserted.
+     * @param element element to be inserted.
+     * @throws    IndexOutOfBoundsException if index is out of range
+     *            <tt>(index &lt; 0 || index &gt; size())</tt>.
+     */
+    public synchronized void add(int index, E element) {
+        int len = array.length;
+        if (index > len || index < 0)
+            throw new IndexOutOfBoundsException("Index: "+index+", Size: "+len);
+
+        E[] newArray = (E[]) new Object[len+1];
+        System.arraycopy(array, 0, newArray, 0, index);
+        newArray[index] = element;
+        System.arraycopy(array, index, newArray, index+1, len - index);
+        array = newArray;
+    }
+
+    /**
+     * Removes the element at the specified position in this list.
+     * Shifts any subsequent elements to the left (subtracts one from their
+     * indices).
+     *
+     * @param index the index of the element to removed.
+     * @return the element that was removed from the list.
+     * @throws    IndexOutOfBoundsException if index out of range <tt>(index
+     *            &lt; 0 || index &gt;= size())</tt>.
+     */
+    public synchronized E remove(int index) {
+        int len = array.length;
+        rangeCheck(index, len);
+        E oldValue = array[index];
+        E[] newArray = (E[]) new Object[len-1];
+        System.arraycopy(array, 0, newArray, 0, index);
+        int numMoved = len - index - 1;
+        if (numMoved > 0)
+            System.arraycopy(array, index+1, newArray, index, numMoved);
+        array = newArray;
+        return oldValue;
+    }
+
+    /**
+     * Removes a single instance of the specified element from this
+     * list, if it is present (optional operation).  More formally,
+     * removes an element <tt>e</tt> such that <tt>(o==null ? e==null :
+     * o.equals(e))</tt>, if the list contains one or more such
+     * elements.  Returns <tt>true</tt> if the list contained the
+     * specified element (or equivalently, if the list changed as a
+     * result of the call).<p>
+     *
+     * @param o element to be removed from this list, if present.
+     * @return <tt>true</tt> if the list contained the specified element.
+     */
+    public synchronized boolean remove(Object o) {
+        int len = array.length;
+        if (len == 0) return false;
+
+        // Copy while searching for element to remove
+        // This wins in the normal case of element being present
+
+        int newlen = len-1;
+        E[] newArray = (E[]) new Object[newlen];
+
+        for (int i = 0; i < newlen; ++i) {
+            if (o == array[i] ||
+            (o != null && o.equals(array[i]))) {
+                // found one;  copy remaining and exit
+                for (int k = i + 1; k < len; ++k) newArray[k-1] = array[k];
+                array = newArray;
+                return true;
+            } else
+                newArray[i] = array[i];
+        }
+        // special handling for last cell
+
+        if (o == array[newlen] ||
+        (o != null && o.equals(array[newlen]))) {
+            array = newArray;
+            return true;
+        } else
+            return false; // throw away copy
+    }
+
+
+    /**
+     * Removes from this List all of the elements whose index is between
+     * fromIndex, inclusive and toIndex, exclusive.  Shifts any succeeding
+     * elements to the left (reduces their index).
+     * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
+     * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
+     *
+     * @param fromIndex index of first element to be removed.
+     * @param toIndex index after last element to be removed.
+     * @throws IndexOutOfBoundsException fromIndex or toIndex out of
+     *              range (fromIndex &lt; 0 || fromIndex &gt;= size() || toIndex
+     *              &gt; size() || toIndex &lt; fromIndex).
+     */
+    private synchronized void removeRange(int fromIndex, int toIndex) {
+        int len = array.length;
+
+        if (fromIndex < 0 || fromIndex >= len ||
+        toIndex > len || toIndex < fromIndex)
+            throw new IndexOutOfBoundsException();
+
+        int numMoved = len - toIndex;
+        int newlen = len - (toIndex-fromIndex);
+        E[] newArray = (E[]) new Object[newlen];
+        System.arraycopy(array, 0, newArray, 0, fromIndex);
+        System.arraycopy(array, toIndex, newArray, fromIndex, numMoved);
+        array = newArray;
+    }
+
+
+    /**
+     * Append the element if not present.
+     * @param element element to be added to this Collection, if absent.
+     * @return true if added
+     **/
+    public synchronized boolean addIfAbsent(E element) {
+        // Copy while checking if already present.
+        // This wins in the most common case where it is not present
+        int len = array.length;
+        E[] newArray = (E[]) new Object[len + 1];
+        for (int i = 0; i < len; ++i) {
+            if (element == array[i] ||
+            (element != null && element.equals(array[i])))
+                return false; // exit, throwing away copy
+            else
+                newArray[i] = array[i];
+        }
+        newArray[len] = element;
+        array = newArray;
+        return true;
+    }
+
+    /**
+     * Returns true if this Collection contains all of the elements in the
+     * specified Collection.
+     * <p>
+     * This implementation iterates over the specified Collection, checking
+     * each element returned by the Iterator in turn to see if it's
+     * contained in this Collection.  If all elements are so contained
+     * true is returned, otherwise false.
+     * @param c the collection
+     * @return true if all elements are contained
+     */
+    public boolean containsAll(Collection<?> c) {
+        E[] elementData = array();
+        int len = elementData.length;
+        Iterator e = c.iterator();
+        while (e.hasNext())
+            if (indexOf(e.next(), elementData, len) < 0)
+                return false;
+
+        return true;
+    }
+
+
+    /**
+     * Removes from this Collection all of its elements that are contained in
+     * the specified Collection. This is a particularly expensive operation
+     * in this class because of the need for an internal temporary array.
+     * <p>
+     *
+     * @param c the collection
+     * @return true if this Collection changed as a result of the call.
+     */
+    public synchronized boolean removeAll(Collection<?> c) {
+        E[] elementData = array;
+        int len = elementData.length;
+        if (len == 0) return false;
+
+        // temp array holds those elements we know we want to keep
+        E[] temp = (E[]) new Object[len];
+        int newlen = 0;
+        for (int i = 0; i < len; ++i) {
+            E element = elementData[i];
+            if (!c.contains(element)) {
+                temp[newlen++] = element;
+            }
+        }
+
+        if (newlen == len) return false;
+
+        //  copy temp as new array
+        E[] newArray = (E[]) new Object[newlen];
+        System.arraycopy(temp, 0, newArray, 0, newlen);
+        array = newArray;
+        return true;
+    }
+
+    /**
+     * Retains only the elements in this Collection that are contained in the
+     * specified Collection (optional operation).  In other words, removes from
+     * this Collection all of its elements that are not contained in the
+     * specified Collection.
+     * @param c the collection
+     * @return true if this Collection changed as a result of the call.
+     */
+    public synchronized boolean retainAll(Collection<?> c) {
+        E[] elementData = array;
+        int len = elementData.length;
+        if (len == 0) return false;
+
+        E[] temp = (E[]) new Object[len];
+        int newlen = 0;
+        for (int i = 0; i < len; ++i) {
+            E element = elementData[i];
+            if (c.contains(element)) {
+                temp[newlen++] = element;
+            }
+        }
+
+        if (newlen == len) return false;
+
+        E[] newArray = (E[]) new Object[newlen];
+        System.arraycopy(temp, 0, newArray, 0, newlen);
+        array = newArray;
+        return true;
+    }
+
+    /**
+     * Appends all of the elements in the specified Collection that
+     * are not already contained in this list, to the end of
+     * this list, in the order that they are returned by the
+     * specified Collection's Iterator.
+     *
+     * @param c elements to be added into this list.
+     * @return the number of elements added
+     */
+    public synchronized int addAllAbsent(Collection<? extends E> c) {
+        int numNew = c.size();
+        if (numNew == 0) return 0;
+
+        E[] elementData = array;
+        int len = elementData.length;
+
+        E[] temp = (E[]) new Object[numNew];
+        int added = 0;
+        Iterator<? extends E> e = c.iterator();
+        while (e.hasNext()) {
+            E element = e.next();
+            if (indexOf(element, elementData, len) < 0) {
+                if (indexOf(element, temp, added) < 0) {
+                    temp[added++] = element;
+                }
+            }
+        }
+
+        if (added == 0) return 0;
+
+        E[] newArray = (E[]) new Object[len+added];
+        System.arraycopy(elementData, 0, newArray, 0, len);
+        System.arraycopy(temp, 0, newArray, len, added);
+        array = newArray;
+        return added;
+    }
+
+    /**
+     * Removes all of the elements from this list.
+     *
+     */
+    public synchronized void clear() {
+        array = (E[]) new Object[0];
+    }
+
+    /**
+     * Appends all of the elements in the specified Collection to the end of
+     * this list, in the order that they are returned by the
+     * specified Collection's Iterator.
+     *
+     * @param c elements to be inserted into this list.
+     * @return true if any elements are added
+     */
+    public synchronized boolean addAll(Collection<? extends E> c) {
+        int numNew = c.size();
+        if (numNew == 0) return false;
+
+        int len = array.length;
+        E[] newArray = (E[]) new Object[len+numNew];
+        System.arraycopy(array, 0, newArray, 0, len);
+        Iterator<? extends E> e = c.iterator();
+        for (int i=0; i<numNew; i++)
+            newArray[len++] = e.next();
+        array = newArray;
+
+        return true;
+    }
+
+    /**
+     * Inserts all of the elements in the specified Collection into this
+     * list, starting at the specified position.  Shifts the element
+     * currently at that position (if any) and any subsequent elements to
+     * the right (increases their indices).  The new elements will appear
+     * in the list in the order that they are returned by the
+     * specified Collection's iterator.
+     *
+     * @param index index at which to insert first element
+     *                from the specified collection.
+     * @param c elements to be inserted into this list.
+     * @throws IndexOutOfBoundsException index out of range (index
+     *              &lt; 0 || index &gt; size()).
+     * @return true if any elements are added
+     */
+    public synchronized boolean addAll(int index, Collection<? extends E> c) {
+        int len = array.length;
+        if (index > len || index < 0)
+            throw new IndexOutOfBoundsException("Index: "+index+", Size: "+len);
+
+        int numNew = c.size();
+        if (numNew == 0) return false;
+
+        E[] newArray = (E[]) new Object[len+numNew];
+        System.arraycopy(array, 0, newArray, 0, len);
+        int numMoved = len - index;
+        if (numMoved > 0)
+            System.arraycopy(array, index, newArray, index + numNew, numMoved);
+        Iterator<? extends E> e = c.iterator();
+        for (int i=0; i<numNew; i++)
+            newArray[index++] = e.next();
+        array = newArray;
+
+        return true;
+    }
+
+    /**
+     * Check if the given index is in range.  If not, throw an appropriate
+     * runtime exception.
+     */
+    private void rangeCheck(int index, int length) {
+        if (index >= length || index < 0)
+            throw new IndexOutOfBoundsException("Index: "+index+", Size: "+ length);
+    }
+
+    /**
+     * Save the state of the list to a stream (i.e., serialize it).
+     *
+     * @serialData The length of the array backing the list is emitted
+     *               (int), followed by all of its elements (each an Object)
+     *               in the proper order.
+     * @param s the stream
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException{
+
+        // Write out element count, and any hidden stuff
+        s.defaultWriteObject();
+
+        E[] elementData = array();
+        // Write out array length
+        s.writeInt(elementData.length);
+
+        // Write out all elements in the proper order.
+        for (int i=0; i<elementData.length; i++)
+            s.writeObject(elementData[i]);
+    }
+
+    /**
+     * Reconstitute the list from a stream (i.e., deserialize it).
+     * @param s the stream
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+
+        // Read in size, and any hidden stuff
+        s.defaultReadObject();
+
+        // Read in array length and allocate array
+        int arrayLength = s.readInt();
+        E[] elementData = (E[]) new Object[arrayLength];
+
+        // Read in all elements in the proper order.
+        for (int i=0; i<elementData.length; i++)
+            elementData[i] = (E) s.readObject();
+        array = elementData;
+    }
+
+    /**
+     * Returns a string representation of this Collection, containing
+     * the String representation of each element.
+     */
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        Iterator e = iterator();
+        buf.append("[");
+        int maxIndex = size() - 1;
+        for (int i = 0; i <= maxIndex; i++) {
+            buf.append(String.valueOf(e.next()));
+            if (i < maxIndex)
+                buf.append(", ");
+        }
+        buf.append("]");
+        return buf.toString();
+    }
+
+
+    /**
+     * Compares the specified Object with this List for equality.  Returns true
+     * if and only if the specified Object is also a List, both Lists have the
+     * same size, and all corresponding pairs of elements in the two Lists are
+     * <em>equal</em>.  (Two elements <tt>e1</tt> and <tt>e2</tt> are
+     * <em>equal</em> if <tt>(e1==null ? e2==null : e1.equals(e2))</tt>.)
+     * In other words, two Lists are defined to be equal if they contain the
+     * same elements in the same order.
+     * <p>
+     * This implementation first checks if the specified object is this
+     * List. If so, it returns true; if not, it checks if the specified
+     * object is a List. If not, it returns false; if so, it iterates over
+     * both lists, comparing corresponding pairs of elements.  If any
+     * comparison returns false, this method returns false.  If either
+     * Iterator runs out of elements before the other it returns false
+     * (as the Lists are of unequal length); otherwise it returns true when
+     * the iterations complete.
+     *
+     * @param o the Object to be compared for equality with this List.
+     * @return true if the specified Object is equal to this List.
+     */
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (!(o instanceof List))
+            return false;
+
+        List<E> l2 = (List<E>)(o);
+        if (size() != l2.size())
+            return false;
+
+        ListIterator<E> e1 = listIterator();
+        ListIterator<E> e2 = l2.listIterator();
+        while(e1.hasNext()) {
+            E o1 = e1.next();
+            E o2 = e2.next();
+            if (!(o1==null ? o2==null : o1.equals(o2)))
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns the hash code value for this List.  
+     *
+     * <p> This implementation uses the definition in {@link
+     * List#hashCode}.
+     * @return the hash code
+     */
+    public int hashCode() {
+        int hashCode = 1;
+        Iterator<E> i = iterator();
+        while (i.hasNext()) {
+            E obj = i.next();
+            hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
+        }
+        return hashCode;
+    }
+
+    /**
+     * Returns an Iterator over the elements contained in this collection.
+     * The iterator provides a snapshot of the state of the list
+     * 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 the iterator
+     */
+    public Iterator<E> iterator() {
+        return new COWIterator<E>(array(), 0);
+    }
+
+    /**
+     * Returns an Iterator of the elements in this List (in proper sequence).
+     * The iterator provides a snapshot of the state of the list
+     * when the iterator was constructed. No synchronization is
+     * needed while traversing the iterator. The iterator does
+     * <em>NOT</em> support the <tt>remove</tt>, <tt>set</tt>,
+     * or <tt>add</tt> methods.
+     * @return the iterator
+     *
+     */
+    public ListIterator<E> listIterator() {
+        return new COWIterator<E>(array(), 0);
+    }
+
+    /**
+     * Returns a ListIterator of the elements in this List (in proper
+     * sequence), starting at the specified position in the List.  The
+     * specified index indicates the first element that would be returned by
+     * an initial call to nextElement.  An initial call to previousElement
+     * would return the element with the specified index minus one.
+     * The ListIterator returned by this implementation will throw
+     * an UnsupportedOperationException in its remove, set and
+     * add methods.
+     *
+     * @param index index of first element to be returned from the
+     *                ListIterator (by a call to getNext).
+     * @return the iterator
+     * @throws IndexOutOfBoundsException index is out of range
+     *              (index &lt; 0 || index &gt; size()).
+     */
+    public ListIterator<E> listIterator(final int index) {
+        E[] elementData = array();
+        int len = elementData.length;
+        if (index<0 || index>len)
+            throw new IndexOutOfBoundsException("Index: "+index);
+
+        return new COWIterator<E>(array(), index);
+    }
+
+    private static class COWIterator<E> implements ListIterator<E> {
+
+        /** Snapshot of the array **/
+        private final E[] array;
+
+        /**
+         * Index of element to be returned by subsequent call to next.
+         */
+        private int cursor;
+
+        private COWIterator(E[] elementArray, int initialCursor) {
+            array = elementArray;
+            cursor = initialCursor;
+        }
+
+        public boolean hasNext() {
+            return cursor < array.length;
+        }
+
+        public boolean hasPrevious() {
+            return cursor > 0;
+        }
+
+        public E next() {
+            try {
+                return array[cursor++];
+            } catch (IndexOutOfBoundsException ex) {
+                throw new NoSuchElementException();
+            }
+        }
+
+        public E previous() {
+            try {
+                return array[--cursor];
+            } catch(IndexOutOfBoundsException e) {
+                throw new NoSuchElementException();
+            }
+        }
+
+        public int nextIndex() {
+            return cursor;
+        }
+
+        public int previousIndex() {
+            return cursor-1;
+        }
+
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException remove is not supported
+         *            by this Iterator.
+         */
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException set is not supported
+         *            by this Iterator.
+         */
+        public void set(E o) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException add is not supported
+         *            by this Iterator.
+         */
+        public void add(E o) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+
+    /**
+     * Returns a view of the portion of this List between fromIndex,
+     * inclusive, and toIndex, exclusive.  The returned List is backed by this
+     * List, so changes in the returned List are reflected in this List, and
+     * vice-versa.  While mutative operations are supported, they are
+     * probably not very useful for CopyOnWriteArrayLists.
+     * <p>
+     * The semantics of the List returned by this method become undefined if
+     * the backing list (i.e., this List) is <i>structurally modified</i> in
+     * any way other than via the returned List.  (Structural modifications are
+     * those that change the size of the List, or otherwise perturb it in such
+     * a fashion that iterations in progress may yield incorrect results.)
+     *
+     * @param fromIndex low endpoint (inclusive) of the subList.
+     * @param toIndex high endpoint (exclusive) of the subList.
+     * @return a view of the specified range within this List.
+     * @throws IndexOutOfBoundsException Illegal endpoint index value
+     *     (fromIndex &lt; 0 || toIndex &gt; size || fromIndex &gt; toIndex).
+     */
+    public synchronized List<E> subList(int fromIndex, int toIndex) {
+        // synchronized since sublist constructor depends on it.
+        int len = array.length;
+        if (fromIndex<0 || toIndex>len  || fromIndex>toIndex)
+            throw new IndexOutOfBoundsException();
+        return new COWSubList<E>(this, fromIndex, toIndex);
+    }
+
+    private static class COWSubList<E> extends AbstractList<E> {
+
+        /*
+          This class extends AbstractList merely for convenience, to
+          avoid having to define addAll, etc. This doesn't hurt, but
+          is wasteful.  This class does not need or use modCount
+          mechanics in AbstractList, but does need to check for
+          concurrent modification using similar mechanics.  On each
+          operation, the array that we expect the backing list to use
+          is checked and updated.  Since we do this for all of the
+          base operations invoked by those defined in AbstractList,
+          all is well.  While inefficient, this is not worth
+          improving.  The kinds of list operations inherited from
+          AbstractList are already so slow on COW sublists that
+          adding a bit more space/time doesn't seem even noticeable.
+         */
+
+        private final CopyOnWriteArrayList<E> l;
+        private final int offset;
+        private int size;
+        private E[] expectedArray;
+
+        private COWSubList(CopyOnWriteArrayList<E> list,
+        int fromIndex, int toIndex) {
+            l = list;
+            expectedArray = l.array();
+            offset = fromIndex;
+            size = toIndex - fromIndex;
+        }
+
+        // only call this holding l's lock
+        private void checkForComodification() {
+            if (l.array != expectedArray)
+                throw new ConcurrentModificationException();
+        }
+
+        // only call this holding l's lock
+        private void rangeCheck(int index) {
+            if (index<0 || index>=size)
+                throw new IndexOutOfBoundsException("Index: "+index+ ",Size: "+size);
+        }
+
+
+        public E set(int index, E element) {
+            synchronized(l) {
+                rangeCheck(index);
+                checkForComodification();
+                E x = l.set(index+offset, element);
+                expectedArray = l.array;
+                return x;
+            }
+        }
+
+        public E get(int index) {
+            synchronized(l) {
+                rangeCheck(index);
+                checkForComodification();
+                return l.get(index+offset);
+            }
+        }
+
+        public int size() {
+            synchronized(l) {
+                checkForComodification();
+                return size;
+            }
+        }
+
+        public void add(int index, E element) {
+            synchronized(l) {
+                checkForComodification();
+                if (index<0 || index>size)
+                    throw new IndexOutOfBoundsException();
+                l.add(index+offset, element);
+                expectedArray = l.array;
+                size++;
+            }
+        }
+
+        public void clear() {
+            synchronized(l) {
+                checkForComodification();
+                l.removeRange(offset, offset+size);
+                expectedArray = l.array;
+                size = 0;
+            }
+        }
+
+        public E remove(int index) {
+            synchronized(l) {
+                rangeCheck(index);
+                checkForComodification();
+                E result = l.remove(index+offset);
+                expectedArray = l.array;
+                size--;
+                return result;
+            }
+        }
+
+        public Iterator<E> iterator() {
+            synchronized(l) {
+                checkForComodification();
+                return new COWSubListIterator<E>(l, 0, offset, size);
+            }
+        }
+
+        public ListIterator<E> listIterator(final int index) {
+            synchronized(l) {
+                checkForComodification();
+                if (index<0 || index>size)
+                    throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
+                return new COWSubListIterator<E>(l, index, offset, size);
+            }
+        }
+
+        public List<E> subList(int fromIndex, int toIndex) {
+            synchronized(l) {
+                checkForComodification();
+                if (fromIndex<0 || toIndex>size)
+                    throw new IndexOutOfBoundsException();
+                return new COWSubList<E>(l, fromIndex+offset, toIndex+offset);
+            }
+        }
+
+    }
+
+
+    private static class COWSubListIterator<E> implements ListIterator<E> {
+        private final ListIterator<E> i;
+        private final int index;
+        private final int offset;
+        private final int size;
+        private COWSubListIterator(List<E> l, int index, int offset, int size) {
+            this.index = index;
+            this.offset = offset;
+            this.size = size;
+            i = l.listIterator(index+offset);
+        }
+
+        public boolean hasNext() {
+            return nextIndex() < size;
+        }
+
+        public E next() {
+            if (hasNext())
+                return i.next();
+            else
+                throw new NoSuchElementException();
+        }
+
+        public boolean hasPrevious() {
+            return previousIndex() >= 0;
+        }
+
+        public E previous() {
+            if (hasPrevious())
+                return i.previous();
+            else
+                throw new NoSuchElementException();
+        }
+
+        public int nextIndex() {
+            return i.nextIndex() - offset;
+        }
+
+        public int previousIndex() {
+            return i.previousIndex() - offset;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        public void set(E o) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void add(E o) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,101 @@
+/*
+ * 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 {@link
+ * java.util.concurrent.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>Mutative operations(add, set, remove, etc) are expensive
+ *      since they usually entail copying the entire underlying array.
+ *  <li>Iterators do not support the mutative remove operation
+ *  <li>Traversal via iterators is very fast and cannot ever 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> Probably the main application
+ * of copy-on-write sets are classes that maintain
+ * sets of Handler objects
+ * that must be multicasted to upon an update command. This
+ * is a classic case where you do not want to be holding a
+ * lock while sending a message, and where traversals normally
+ * vastly overwhelm additions.
+ * <pre>
+ * class Handler { void handle(); ... }
+ *
+ * class X {
+ *    private final CopyOnWriteArraySet&lt;Handler&gt; handlers = new CopyOnWriteArraySet&lt;Handler&gt;();
+ *    public void addHandler(Handler h) { handlers.add(h); }
+ *
+ *    private long internalState;
+ *    private synchronized void changeState() { internalState = ...; }
+ *
+ *    public void update() {
+ *       changeState();
+ *       Iterator it = handlers.iterator();
+ *       while (it.hasNext())
+ *          it.next().handle();
+ *    }
+ * }
+ * </pre>
+ * @see CopyOnWriteArrayList
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../guide/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 CopyOnWriteArraySet<E> extends AbstractSet<E>
+        implements Cloneable, 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
+     */
+    public CopyOnWriteArraySet(Collection<? extends E> c) {
+        al = new CopyOnWriteArrayList<E>();
+        al.addAllAbsent(c);
+    }
+
+
+    public int      size()                    { return al.size(); }
+    public boolean  isEmpty()                 { return al.isEmpty(); }
+    public boolean  contains(Object o)        { return al.contains(o); }
+    public Object[] toArray()                 { return al.toArray(); }
+    public <T> T[]  toArray(T[] a)            { return al.toArray(a); }
+    public void     clear()                   {        al.clear(); }
+    public Iterator<E>  iterator()            { return al.iterator(); }
+    public boolean  remove(Object o)          { return al.remove(o); }
+    public boolean  add(E o)                  { return al.addIfAbsent(o); }
+    public boolean  containsAll(Collection<?> c)      { return al.containsAll(c); }
+    public boolean  addAll(Collection<? extends E> c) { return al.addAllAbsent(c) > 0; }
+    public boolean  removeAll(Collection<?> c)        { return al.removeAll(c); }
+    public boolean  retainAll(Collection<?> c)        { return al.retainAll(c); }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,280 @@
+/*
+ * 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 <tt>CountDownLatch</tt> is initialized with a given
+ * <em>count</em>.  The {@link #await await} methods block until the current
+ * {@link #getCount 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 <tt>CountDownLatch</tt> is a versatile synchronization tool
+ * and can be used for a number of purposes.  A
+ * <tt>CountDownLatch</tt> 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 <tt>CountDownLatch</tt> 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 <tt>CountDownLatch</tt> is that it
+ * doesn't require that threads calling <tt>countDown</tt> 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>
+ *
+ * @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 {
+        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 <tt>CountDownLatch</tt> 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 <tt>count</tt> is less than zero.
+     */
+    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 {@link Thread#interrupt interrupted}.
+     *
+     * <p>If the current {@link #getCount count} is zero then this method
+     * returns immediately.
+     * <p>If the current {@link #getCount 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 {@link 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 {@link 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 {@link Thread#interrupt interrupted},
+     * or the specified waiting time elapses.
+     *
+     * <p>If the current {@link #getCount count} is zero then this method
+     * returns immediately with the value <tt>true</tt>.
+     *
+     * <p>If the current {@link #getCount 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 {@link 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 <tt>true</tt>.
+     * <p>If the current thread:
+     * <ul>
+     * <li>has its interrupted status set on entry to this method; or 
+     * <li>is {@link 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 <tt>false</tt>
+     * 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 <tt>timeout</tt> argument.
+     * @return <tt>true</tt> if the count reached zero  and <tt>false</tt>
+     * 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 {@link #getCount 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 {@link #getCount 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 
+     * &quot;Count =&quot; 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() + "]";
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,430 @@
+/*
+ * 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 a fast-fail 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, even those that have not yet resumed
+ * from a previous {@link #await}. will also leave abnormally via
+ * {@link BrokenBarrierException} (or <tt>InterruptedException</tt> if
+ * they too were interrupted at about the same time).
+ *
+ * @since 1.5
+ * @see CountDownLatch
+ *
+ * @author Doug Lea
+ */
+public class CyclicBarrier {
+    /** 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 generation number. Incremented upon barrier trip.
+     * Retracted upon reset.
+     */
+    private long generation; 
+
+    /** 
+     * Breakage indicator.
+     */
+    private boolean broken; 
+
+    /**
+     * Number of parties still waiting. Counts down from parties to 0
+     * on each cycle.
+     */
+    private int count; 
+
+    /**
+     * Updates state on barrier trip and wake up everyone.
+     */  
+    private void nextGeneration() {
+        count = parties;
+        ++generation;
+        trip.signalAll();
+    }
+
+    /**
+     * Sets barrier as broken and wake up everyone
+     */
+    private void breakBarrier() {
+        broken = true;
+        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 {
+            int index = --count;
+            long g = generation;
+
+            if (broken) 
+                throw new BrokenBarrierException();
+
+            if (Thread.interrupted()) {
+                breakBarrier();
+                throw new InterruptedException();
+            }
+
+            if (index == 0) {  // tripped
+                nextGeneration();
+                boolean ranAction = false;
+                try {
+                    Runnable command = barrierCommand;
+                    if (command != null) 
+                        command.run();
+                    ranAction = true;
+                    return 0;
+                } finally {
+                    if (!ranAction)
+                        breakBarrier();
+                }
+            }
+
+            for (;;) {
+                try {
+                    if (!timed) 
+                        trip.await();
+                    else if (nanos > 0L)
+                        nanos = trip.awaitNanos(nanos);
+                } catch (InterruptedException ie) {
+                    breakBarrier();
+                    throw ie;
+                }
+                
+                if (broken || 
+                    g > generation) // true if a reset occurred while waiting
+                    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 <tt>null</tt> if there is no action.
+     *
+     * @throws IllegalArgumentException if <tt>parties</tt> 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 upon each barrier.
+     *
+     * @param parties the number of threads that must invoke {@link #await}
+     * before the barrier is tripped.
+     *
+     * @throws IllegalArgumentException if <tt>parties</tt> 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 {@link #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 following things happens:
+     * <ul>
+     * <li>The last thread arrives; or
+     * <li>Some other thread {@link Thread#interrupt interrupts} the current
+     * thread; or
+     * <li>Some other thread  {@link 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 {@link 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 {@link #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 {@link 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 while the current thread was waiting, or the barrier was
+     * reset, or the barrier was broken when <tt>await</tt> 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 {@link #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>The specified timeout elapses; or
+     * <li>Some other thread {@link Thread#interrupt interrupts} the current
+     * thread; or
+     * <li>Some other thread  {@link 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 {@link 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 {@link #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 {@link 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 while the current thread was waiting, or the barrier was
+     * reset, or the barrier was broken when <tt>await</tt> 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 <tt>true</tt> 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; 
+     * and <tt>false</tt> otherwise.
+     */
+    public boolean isBroken() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return 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 {
+            /*
+             * Retract generation number enough to cover threads
+             * currently waiting on current and still resuming from
+             * previous generation, plus similarly accommodating spans
+             * after the reset.
+             */
+            generation -= 4;
+            broken = false;
+            trip.signalAll();
+        } 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();
+        }
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/DelayQueue.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/DelayQueue.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/DelayQueue.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/DelayQueue.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,366 @@
+/*
+ * 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>.
+ * This queue does not permit <tt>null</tt> elements.
+ * <p>This class implements 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}/../guide/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
+     * @throws NullPointerException if <tt>c</tt> or any element within it
+     * is <tt>null</tt>
+     *
+     */
+    public DelayQueue(Collection<? extends E> c) {
+        this.addAll(c);
+    }
+
+    /**
+     * Inserts the specified element into this delay queue.
+     *
+     * @param o the element to add
+     * @return <tt>true</tt>
+     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     */
+    public boolean offer(E o) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            E first = q.peek();
+            q.offer(o);
+            if (first == null || o.compareTo(first) < 0)
+                available.signalAll();
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+
+    /**
+     * Adds the specified element to this delay queue. As the queue is
+     * unbounded this method will never block.
+     * @param o the element to add
+     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     */
+    public void put(E o) {
+        offer(o);
+    }
+
+    /**
+     * Inserts the specified element into this delay queue. As the queue is
+     * unbounded this method will never block.
+     * @param o 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 if the specified element is <tt>null</tt>.
+     */
+    public boolean offer(E o, long timeout, TimeUnit unit) {
+        return offer(o);
+    }
+
+    /**
+     * Adds the specified element to this queue.
+     * @param o the element to add
+     * @return <tt>true</tt> (as per the general contract of
+     * <tt>Collection.add</tt>).
+     *
+     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     */
+    public boolean add(E o) {
+        return offer(o);
+    }
+
+    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();
+        }
+    }
+
+    public E poll(long time, TimeUnit unit) throws InterruptedException {
+        final ReentrantLock lock = this.lock;
+        lock.lockInterruptibly();
+        long nanos = unit.toNanos(time);
+        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 (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();
+        }
+    }
+
+
+    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();
+        }
+    }
+
+    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();
+        }
+    }
+
+    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();
+        }
+    }
+
+    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.
+     */
+    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;
+    }
+
+    public Object[] toArray() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return q.toArray();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public <T> T[] toArray(T[] array) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return q.toArray(array);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public boolean remove(Object o) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return q.remove(o);
+        } 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 iterator is a thread-safe "fast-fail" iterator that will
+     * throw {@link java.util.ConcurrentModificationException}
+     * upon detected interference.
+     *
+     * @return an iterator over the elements in this queue.
+     */
+    public Iterator<E> iterator() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return new Itr(q.iterator());
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    private class Itr<E> implements Iterator<E> {
+        private final Iterator<E> iter;
+        Itr(Iterator<E> i) {
+            iter = i;
+        }
+
+        public boolean hasNext() {
+            return iter.hasNext();
+        }
+
+        public E next() {
+            final ReentrantLock lock = DelayQueue.this.lock;
+            lock.lock();
+            try {
+                return iter.next();
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public void remove() {
+            final ReentrantLock lock = DelayQueue.this.lock;
+            lock.lock();
+            try {
+                iter.remove();
+            } finally {
+                lock.unlock();
+            }
+        }
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/DelayQueue.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message