You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by nd...@apache.org on 2006/07/12 06:12:08 UTC

svn commit: r421111 [11/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...

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,1117 @@
+/*
+ * 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.  When constructed as fair, threads
+ * contend for entry using an approximately arrival-order policy. When
+ * the write lock is released either the longest-waiting single writer
+ * will be assigned the write lock, or if there is a reader waiting
+ * longer than any writer, the set of readers will be assigned the
+ * read lock.  When constructed as non-fair, the order of entry to the
+ * lock need not be in arrival order.  In either case, if readers are
+ * active and a writer enters the lock then no subsequent readers will
+ * be granted the read lock until after that writer has acquired and
+ * released the write lock.
+ * 
+ * <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}. 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
+ * <tt>readLock().newCondition()</tt> throws 
+ * <tt>UnsupportedOperationException</tt>.
+ *
+ * <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) {
+ *        // upgrade lock manually
+ *        rwl.readLock().unlock();   // must unlock first to obtain writelock
+ *        rwl.writeLock().lock();
+ *        if (!cacheValid) { // recheck
+ *          data = ...
+ *          cacheValid = true;
+ *        }
+ *        // downgrade lock
+ *        rwl.readLock().lock();  // reacquire read without giving up write 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>
+ * class RWDictionary {
+ *    private final Map&lt;String, Data&gt;  m = new TreeMap&lt;String, Data&gt;();
+ *    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>A reentrant write lock intrinsically defines an owner and can
+ * only be released by the thread that acquired it.  In contrast, in
+ * this implementation, the read lock has no concept of ownership, and
+ * there is no requirement that the thread releasing a read lock is
+ * the same as the one that acquired it.  However, this property is
+ * not guaranteed to hold in future implementations of this class.
+ *
+ * <p> This lock supports a maximum of 65536 recursive write locks
+ * and 65536 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 <tt>ReentrantReadWriteLock</tt> with
+     * default ordering properties.
+     */
+    public ReentrantReadWriteLock() {
+        sync = new NonfairSync();
+        readerLock = new ReadLock(this);
+        writerLock = new WriteLock(this);
+    }
+
+    /**
+     * Creates a new <tt>ReentrantReadWriteLock</tt> with
+     * the given fairness policy.
+     *
+     * @param fair 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; }
+
+    /* 
+     * 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 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; }
+
+    /** 
+     * Synchronization implementation for ReentrantReadWriteLock.
+     * Subclassed into fair and nonfair versions.
+     */
+    abstract static class Sync extends AbstractQueuedSynchronizer {
+        /** Current (exclusive) owner thread */
+        transient Thread owner;
+
+        /**
+         * Perform write lock. Allows fast path in non-fair version.
+         */
+        abstract void wlock();
+
+        /** 
+         * Perform non-fair tryLock for write.  tryAcquire is
+         * implemented in subclasses, but both versions need nonfair
+         * try for trylock method
+         */
+        final boolean nonfairTryAcquire(int acquires) {
+            // mask out readlocks if called from condition methods
+            acquires = exclusiveCount(acquires);
+            Thread current = Thread.currentThread();
+            int c = getState();
+            int w = exclusiveCount(c);
+            if (w + acquires >= SHARED_UNIT)
+                throw new Error("Maximum lock count exceeded");
+            if (c != 0 && (w == 0 || current != owner))
+                return false;
+            if (!compareAndSetState(c, c + acquires)) 
+                return false;
+            owner = current;
+            return true;
+        }
+
+        /** 
+         * Perform nonfair tryLock for read. 
+         */
+        final int nonfairTryAcquireShared(int acquires) {
+            for (;;) {
+                int c = getState();
+                int nextc = c + (acquires << SHARED_SHIFT);
+                if (nextc < c)
+                    throw new Error("Maximum lock count exceeded");
+                if (exclusiveCount(c) != 0 && 
+                    owner != Thread.currentThread())
+                    return -1;
+                if (compareAndSetState(c, nextc)) 
+                    return 1;
+                // Recheck count if lost CAS
+            }
+        }
+
+        protected final boolean tryRelease(int releases) {
+            Thread current = Thread.currentThread();
+            int c = getState();
+            if (owner != current)
+                throw new IllegalMonitorStateException();
+            int nextc = c - releases;
+            boolean free = false;
+            if (exclusiveCount(c) == releases) {
+                free = true;
+                owner = null;
+            }
+            setState(nextc);
+            return free;
+        }
+
+        protected final boolean tryReleaseShared(int releases) {
+            for (;;) {
+                int c = getState();
+                int nextc = c - (releases << SHARED_SHIFT);
+                if (nextc < 0)
+                    throw new IllegalMonitorStateException();
+                if (compareAndSetState(c, nextc)) 
+                    return nextc == 0;
+            }
+        }
+    
+        protected final boolean isHeldExclusively() {
+            return exclusiveCount(getState()) != 0 && 
+                owner == Thread.currentThread();
+        }
+
+        // Methods relayed to outer class
+        
+        final ConditionObject newCondition() { 
+            return new ConditionObject(); 
+        }
+
+        final Thread getOwner() {
+            int c = exclusiveCount(getState());
+            Thread o = owner;
+            return (c == 0)? null : o;
+        }
+        
+        final int getReadLockCount() {
+            return sharedCount(getState());
+        }
+        
+        final boolean isWriteLocked() {
+            return exclusiveCount(getState()) != 0;
+        }
+
+        final int getWriteHoldCount() {
+            int c = exclusiveCount(getState());
+            Thread o = owner;
+            return (o == Thread.currentThread())? c : 0;
+        }
+
+        /**
+         * 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();
+            setState(0); // reset to unlocked state
+        }
+
+        final int getCount() { return getState(); }
+    }
+
+    /** 
+     * Nonfair version of Sync
+     */
+    final static class NonfairSync extends Sync {
+        protected final boolean tryAcquire(int acquires) { 
+            return nonfairTryAcquire(acquires);
+        }
+
+        protected final int tryAcquireShared(int acquires) {
+            return nonfairTryAcquireShared(acquires);
+        }
+
+        // Use fastpath for main write lock method
+        final void wlock() {
+            if (compareAndSetState(0, 1))
+                owner = Thread.currentThread();
+            else
+                acquire(1);
+        }
+    }
+
+    /** 
+     * Fair version of Sync
+     */
+    final static class FairSync extends Sync {
+        protected final boolean tryAcquire(int acquires) { 
+            // mask out readlocks if called from condition methods
+            acquires = exclusiveCount(acquires);
+            Thread current = Thread.currentThread();
+            Thread first;
+            int c = getState();
+            int w = exclusiveCount(c);
+            if (w + acquires >= SHARED_UNIT)
+                throw new Error("Maximum lock count exceeded");
+            if ((w == 0 || current != owner) &&
+                (c != 0 || 
+                 ((first = getFirstQueuedThread()) != null && 
+                  first != current)))
+                return false;
+            if (!compareAndSetState(c, c + acquires)) 
+                return false;
+            owner = current;
+            return true;
+        }
+
+        protected final int tryAcquireShared(int acquires) {
+            Thread current = Thread.currentThread();
+            for (;;) {
+                Thread first = getFirstQueuedThread();
+                if (first != null && first != current)
+                    return -1;
+                int c = getState();
+                int nextc = c + (acquires << SHARED_SHIFT);
+                if (nextc < c)
+                    throw new Error("Maximum lock count exceeded");
+                if (exclusiveCount(c) != 0 && 
+                    owner != Thread.currentThread())
+                    return -1;
+                if (compareAndSetState(c, nextc)) 
+                    return 1;
+                // Recheck count if lost CAS
+            }
+        }
+
+        final void wlock() { // no fast path
+            acquire(1);
+        }
+    }
+
+    /**
+     * 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 lock null
+         */
+        protected ReadLock(ReentrantReadWriteLock lock) {
+            sync = lock.sync;
+        }
+
+        /**
+         * Acquires the shared lock. 
+         *
+         * <p>Acquires the lock if it is not held exclusively by
+         * another thread and returns immediately.
+         *
+         * <p>If the lock is held exclusively by another thread then
+         * the current thread becomes disabled for thread scheduling
+         * purposes and lies dormant until the lock has been acquired.
+         */
+        public void lock() { 
+            sync.acquireShared(1);
+        }
+
+        /**
+         * Acquires the shared lock unless the current thread is 
+         * {@link Thread#interrupt interrupted}.
+         *
+         * <p>Acquires the shared lock if it is not held exclusively
+         * by another thread and 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 {@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 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.acquireSharedInterruptibly(1);
+        }
+
+        /**
+         * Acquires the shared lock only if it is not held exclusively by
+         * another thread at the time of invocation.
+         *
+         * <p>Acquires the lock if it is not held exclusively by
+         * another thread and returns immediately with the value
+         * <tt>true</tt>. Even when this lock has been set to use a
+         * fair ordering policy, a call to <tt>tryLock()</tt>
+         * <em>will</em> immediately acquire the lock if it is
+         * available, whether or not other threads are currently
+         * waiting for the lock.  This &quot;barging&quot; 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 lock is held exclusively by another thread then
+         * this method will return immediately with the value
+         * <tt>false</tt>.
+         *
+         * @return <tt>true</tt> if the lock was acquired.
+         */
+        public  boolean tryLock() {
+            return sync.nonfairTryAcquireShared(1) >= 0;
+        }
+
+        /**
+         * Acquires the shared lock if it is not held exclusively by
+         * another thread within the given waiting time and the
+         * current thread has not been {@link Thread#interrupt
+         * interrupted}.
+         *
+         * <p>Acquires the lock if it is not held exclusively by
+         * another thread and returns immediately with the value
+         * <tt>true</tt>. 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 <tt>tryLock</tt> 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 lock is held exclusively 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 {@link Thread#interrupt interrupts} the current
+         * thread; or
+         *
+         * <li>The specified waiting time elapses
+         *
+         * </ul>
+         *
+         * <p>If the lock is acquired then the value <tt>true</tt> is
+         * returned.
+         *
+         * <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 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
+         * <tt>false</tt> 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 <tt>true</tt> if the lock was acquired.
+         *
+         * @throws InterruptedException if the current thread is interrupted
+         * @throws NullPointerException if 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 other lock attempts.
+         */
+        public  void unlock() {
+            sync.releaseShared(1);
+        }
+
+        /**
+         * Throws UnsupportedOperationException because 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 
+         * &quot;Read locks =&quot; 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 lock null
+         */
+        protected WriteLock(ReentrantReadWriteLock lock) {
+            sync = lock.sync;
+        }
+
+        /**
+         * Acquire 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.wlock();
+        }
+
+        /**
+         * Acquires the lock unless the current thread is {@link
+         * 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 {@link 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 {@link 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 <tt>true</tt>,
+         * setting the lock hold count to one. Even when this lock has
+         * been set to use a fair ordering policy, a call to
+         * <tt>tryLock()</tt> <em>will</em> immediately acquire the
+         * lock if it is available, whether or not other threads are
+         * currently waiting for the lock.  This &quot;barging&quot;
+         * 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
+         * <tt>true</tt>.
+         *
+         * <p>If the lock is held by another thread then this method
+         * will return immediately with the value <tt>false</tt>.
+         *
+         * @return <tt>true</tt> if the lock was free and was acquired by the
+         * current thread, or the lock was already held by the current thread; and
+         * <tt>false</tt> 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 {@link Thread#interrupt interrupted}.
+         *
+         * <p>Acquires the lock if it is not held by another thread
+         * and returns immediately with the value <tt>true</tt>,
+         * 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 <tt>tryLock</tt>
+         * 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
+         * <tt>true</tt>.
+         *
+         * <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 {@link Thread#interrupt interrupts}
+         * the current thread; or
+         *
+         * <li>The specified waiting time elapses
+         *
+         * </ul>
+         *
+         * <p>If the lock is acquired then the value <tt>true</tt> 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 {@link 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
+         * <tt>false</tt> 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 <tt>true</tt> if the lock was free and was acquired
+         * by the current thread, or the lock was already held by the
+         * current thread; and <tt>false</tt> if the waiting time
+         * elapsed before the lock could be acquired.
+         *
+         * @throws InterruptedException if the current thread is interrupted
+         * @throws NullPointerException if 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 access the write
+         * lock.)
+         *
+         * <li>When the condition {@link 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 {@link 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
+         * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
+         * followed by the {@link Thread#getName} of the owning thread.
+         * @return a string identifying this lock, as well as its lock state.
+         */
+        public String toString() {
+            Thread owner = sync.getOwner();
+            return super.toString() + ((owner == null) ?
+                                       "[Unlocked]" :
+                                       "[Locked by thread " + owner.getName() + "]");
+        }
+
+    }
+
+
+    // Instrumentation and status
+
+    /**
+     * Returns true if this lock has fairness set true.
+     * @return true if this lock has fairness set true.
+     */
+    public final boolean isFair() {
+        return sync instanceof FairSync;
+    }
+
+    /**
+     * Returns the thread that currently owns the exclusive lock, or
+     * <tt>null</tt> if not owned. Note that the owner may be
+     * momentarily <tt>null</tt> 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 <tt>null</tt> 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 <tt>true</tt> if any thread holds write lock and 
+     * <tt>false</tt> otherwise.
+     */
+    public boolean isWriteLocked() {
+        return sync.isWriteLocked();
+    }
+
+    /**
+     * Queries if the write lock is held by the current thread. 
+     * @return <tt>true</tt> if current thread holds this lock and 
+     * <tt>false</tt> 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 this lock by the current thread,
+     * or zero if this lock is not held by the current thread.
+     */
+    public int getWriteHoldCount() {
+        return sync.getWriteHoldCount();
+    }
+
+    /**
+     * 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. Note that
+     * because cancellations may occur at any time, a <tt>true</tt>
+     * 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 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
+     * <tt>true</tt> return does not guarantee that this thread
+     * will ever acquire.  This method is designed primarily for use
+     * in monitoring of the system state.
+     *
+     * @param thread the thread
+     * @return true if the given thread is queued waiting for this lock.
+     * @throws NullPointerException if thread is null
+     */
+    public final boolean hasQueuedThread(Thread thread) { 
+        return sync.isQueued(thread);
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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 <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 this lock 
+     * is not held
+     * @throws IllegalArgumentException if the given condition is
+     * not associated with this lock
+     * @throws NullPointerException if condition 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 condition 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 condition 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 &quot;Write locks =&quot;
+     * follwed by the number of reentrantly held write locks, and the
+     * String &quot;Read locks =&quot; 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 = exclusiveCount(c);
+        int r = sharedCount(c);
+        
+        return super.toString() + 
+            "[Write locks = " + w + ", Read locks = " + r + "]";
+    }
+
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/locks/package.html
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/locks/package.html?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/locks/package.html (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/locks/package.html Tue Jul 11 21:12:04 2006
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>Locks</title>
+</head>
+
+<body>
+
+Interfaces and classes providing a framework for locking and waiting
+for conditions that is distinct from built-in synchronization and
+monitors. The framework permits much greater flexibility in the use of
+locks and conditions, at the expense of more awkward syntax.
+
+<p> The {@link java.util.concurrent.locks.Lock} interface supports
+locking disciplines that differ in semantics (reentrant, fair, etc),
+and that can be used in non-block-structured contexts including
+hand-over-hand and lock reordering algorithms. The main implementation
+is {@link java.util.concurrent.locks.ReentrantLock}. 
+
+<p> The {@link java.util.concurrent.locks.ReadWriteLock} interface
+similarly defines locks that may be shared among readers but are
+exclusive to writers.  Only a single implementation, {@link
+java.util.concurrent.locks.ReentrantReadWriteLock}, is provided, since
+it covers most standard usage contexts. But programmers may create
+their own implementations to cover nonstandard requirements.
+
+<p> The {@link java.util.concurrent.locks.Condition} interface
+describes condition variables that may be associated with Locks.
+These are similar in usage to the implicit monitors accessed using
+<tt>Object.wait</tt>, but offer extended capabilities.  In particular,
+multiple <tt>Condition</tt> objects may be associated with a single
+<tt>Lock</tt>.  To avoid compatibility issues, the names of
+<tt>Condition</tt> methods are different than the corresponding
+<tt>Object</tt> versions.
+
+<p> The {@link java.util.concurrent.locks.AbstractQueuedSynchronizer}
+class serves as a useful superclass for defining locks and other
+synchronizers that rely on queuing blocked threads.  The {@link
+java.util.concurrent.locks.LockSupport} class provides lower-level
+blocking and unblocking support that is useful for those developers
+implementing their own customized lock classes.
+
+@since 1.5
+
+</body> </html>

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

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/package.html
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/package.html?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/package.html (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/java/util/concurrent/package.html Tue Jul 11 21:12:04 2006
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>Concurrency Utilities</title>
+</head>
+
+<body>
+
+<p> Utility classes commonly useful in concurrent programming.  This
+package includes a few small standardized extensible frameworks, as
+well as some classes that provide useful functionality and are
+otherwise tedious or difficult to implement.  Here are brief
+descriptions of the main components. See also the <tt>locks</tt> and
+<tt>atomic</tt> packages.
+
+<h2>Executors</h2>
+
+<b>Interfaces.</b> {@link java.util.concurrent.Executor} is a simple
+standardized interface for defining custom thread-like subsystems,
+including thread pools, asynchronous IO, and lightweight task
+frameworks.  Depending on which concrete Executor class is being used,
+tasks may execute in a newly created thread, an existing
+task-execution thread, or the thread calling <tt>execute()</tt>, and
+may execute sequentially or concurrently.  {@link
+java.util.concurrent.ExecutorService} provides a more complete
+asynchronous task execution framework.  An ExecutorService manages
+queuing and scheduling of tasks, and allows controlled shutdown.  The
+{@link java.util.concurrent.ScheduledExecutorService} subinterface
+adds support for delayed and periodic task execution.
+ExecutorServices provide methods arranging asynchronous execution of
+any function expressed as {@link java.util.concurrent.Callable}, the
+result-bearing analog of {@link java.lang.Runnable}.  A {@link
+java.util.concurrent.Future} returns the results of a function, allows
+determination of whether execution has completed, and provides a means to
+cancel execution.
+
+<p>
+
+<b>Implementations.</b> Classes {@link
+java.util.concurrent.ThreadPoolExecutor} and {@link
+java.util.concurrent.ScheduledThreadPoolExecutor} provide tunable,
+flexible thread pools. The {@link java.util.concurrent.Executors}
+class provides factory methods for the most common kinds and
+configurations of Executors, as well as a few utility methods for
+using them. Other utilities based on Executors include the concrete
+class {@link java.util.concurrent.FutureTask} providing a common
+extensible implementation of Futures, and {@link
+java.util.concurrent.ExecutorCompletionService}, that assists in
+coordinating the processing of groups of asynchronous tasks.
+
+<h2>Queues</h2>
+
+The java.util.concurrent {@link
+java.util.concurrent.ConcurrentLinkedQueue} class supplies an
+efficient scalable thread-safe non-blocking FIFO queue.  Five
+implementations in java.util.concurrent support the extended {@link
+java.util.concurrent.BlockingQueue} interface, that defines blocking
+versions of put and take: {@link
+java.util.concurrent.LinkedBlockingQueue}, {@link
+java.util.concurrent.ArrayBlockingQueue}, {@link
+java.util.concurrent.SynchronousQueue}, {@link
+java.util.concurrent.PriorityBlockingQueue}, and {@link
+java.util.concurrent.DelayQueue}. The different classes cover the most
+common usage contexts for producer-consumer, messaging, parallel
+tasking, and related concurrent designs.
+
+
+<h2>Timing</h2>
+
+The {@link java.util.concurrent.TimeUnit} class provides multiple
+granularities (including nanoseconds) for specifying and controlling
+time-out based operations. Most classes in the package contain
+operations based on time-outs in addition to indefinite waits.  In all
+cases that time-outs are used, the time-out specifies the minimum time
+that the method should wait before indicating that it
+timed-out. Implementations make a &quot;best effort&quot; to detect
+time-outs as soon as possible after they occur. However, an indefinite
+amount of time may elapse between a time-out being detected and a
+thread actually executing again after that time-out.
+
+<h2>Synchronizers</h2>
+
+Four classes aid common special-purpose synchronization idioms.
+{@link java.util.concurrent.Semaphore} is a classic concurrency tool.
+{@link java.util.concurrent.CountDownLatch} is a very simple yet very
+common utility for blocking until a given number of signals, events,
+or conditions hold.  A {@link java.util.concurrent.CyclicBarrier} is a
+resettable multiway synchronization point useful in some styles of
+parallel programming. An {@link java.util.concurrent.Exchanger} allows
+two threads to exchange objects at a rendezvous point, and is useful
+in several pipeline designs.
+
+<h2>Concurrent Collections</h2>
+
+Besides Queues, this package supplies a few Collection implementations
+designed for use in multithreaded contexts: {@link
+java.util.concurrent.ConcurrentHashMap}, {@link
+java.util.concurrent.CopyOnWriteArrayList}, and {@link
+java.util.concurrent.CopyOnWriteArraySet}.
+
+<p>The "Concurrent" prefix used with some classes in this package is a
+shorthand indicating several differences from similar "synchronized"
+classes. For example <tt>java.util.Hashtable</tt> and
+<tt>Collections.synchronizedMap(new HashMap())</tt> are
+synchronized. But {@link java.util.concurrent.ConcurrentHashMap} is
+"concurrent".  A concurrent collection is thread-safe, but not
+governed by a single exclusion lock. In the particular case of
+ConcurrentHashMap, it safely permits any number of concurrent reads as
+well as a tunable number of concurrent writes.  "Synchronized" classes
+can be useful when you need to prevent all access to a collection via
+a single lock, at the expense of poorer scalability. In other cases in
+which multiple threads are expected to access a common collection,
+"concurrent" versions are normally preferable. And unsynchronized
+collections are preferable when either collections are unshared, or
+are accessible only when holding other locks.
+
+<p> Most concurrent Collection implementations (including most Queues)
+also differ from the usual java.util conventions in that their Iterators
+provide <em>weakly consistent</em> rather than fast-fail traversal. A
+weakly consistent iterator is thread-safe, but does not necessarily
+freeze the collection while iterating, so it may (or may not) reflect
+any updates since the iterator was created.
+
+@since 1.5
+
+</body> </html>

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

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/AtomicSupport.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/AtomicSupport.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/AtomicSupport.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/AtomicSupport.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,353 @@
+/* Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.concurrent;
+
+import java.lang.reflect.Field;
+
+/**
+ * <p>
+ * The SPI that VM implementations must implement to provide support for the
+ * <code>java.util.concurrent.atomic</code> classes and others.
+ * Implementations of this class are registered as <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">Service
+ * Providers<a> as defined by the <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html">JAR File
+ * Specification</a>. The configuration file for this class has a ClassLoader
+ * resource URI of
+ * <code>META-INF/services/org.apache.harmony.concurrent.AtomicSupport</code>.
+ * </p>
+ * 
+ * @see java.util.concurrent.atomic
+ */
+public abstract class AtomicSupport {
+
+    /*
+     * The implementation is currently just a simple singleton, but can change
+     * in the future.
+     */
+    private static AtomicSupport INSTANCE = ServiceLoader.load(AtomicSupport.class);
+
+    /**
+     * <p>
+     * Gets an instance of this service provider. See the class documentation
+     * for details on configuring a provider implementation.
+     * </p>
+     * 
+     * @return An instance of AtomicSupport.
+     * @throws IllegalStateException if an implementation could not be loaded
+     *         for any reason.
+     */
+    public static AtomicSupport getInstance() {
+        if (INSTANCE == null) {
+            throw new IllegalStateException(
+                    "An implementation of AtomicSupport could not be loaded.");
+        }
+        return INSTANCE;
+    }
+
+    /**
+     * <p>
+     * All implementations MUST provide a public, nullary constructor.
+     * </p>
+     */
+    protected AtomicSupport() {
+        super();
+    }
+
+    /**
+     * <p>
+     * Atomically compare and set a boolean value on the field of the object
+     * instance given if the current value equals the expected value.
+     * </p>
+     * 
+     * @param object A non-null instance of the object with a boolean field.
+     * @param field A non-null, {@link Boolean#TYPE} {@link Field} associated
+     *        with <code>object</code>.
+     * @param expectedValue The expected boolean value of <code>field</code>.
+     * @param newValue The new boolean value to set for <code>field</code>.
+     * @return <code>true</code> if the current value ==
+     *         <code>expectedValue</code> and <code>newValue</code>;
+     *         <code>false</code> if not set.
+     */
+    public abstract boolean compareAndSet(Object object, Field field, boolean expectedValue,
+            boolean newValue);
+
+    /**
+     * <p>
+     * Atomically compare and set an int value on the field of the object
+     * instance given if the current value equals the expected value.
+     * </p>
+     * 
+     * @param object A non-null instance of the object with an int field.
+     * @param field A non-null, {@link Integer#TYPE} {@link Field} associated
+     *        with <code>object</code>.
+     * @param expectedValue The expected int value of <code>field</code>.
+     * @param newValue The new int value to set for <code>field</code>.
+     * @return <code>true</code> if the current value ==
+     *         <code>expectedValue</code> and <code>newValue</code>;
+     *         <code>false</code> if not set.
+     */
+    public abstract boolean compareAndSet(Object object, Field field, int expectedValue,
+            int newValue);
+
+    /**
+     * <p>
+     * Atomically compare and set an int value in the int[] given if the current
+     * value equals the expected value.
+     * </p>
+     * 
+     * @param array The non-null int[] to compare and set into.
+     * @param index The index of the int value to compare and set in
+     *        <code>array</code>.
+     * @param expectedValue The expected int value of the element at
+     *        <code>index</code> in <code>array</code>.
+     * @param newValue The new int value to set for <code>field</code>.
+     * @return <code>true</code> if the current value ==
+     *         <code>expectedValue</code> and <code>newValue</code>;
+     *         <code>false</code> if not set.
+     */
+    public abstract boolean compareAndSet(int[] array, int index, int expectedValue,
+            int newValue);
+
+    /**
+     * <p>
+     * Atomically compare and set a long value on the field of the object
+     * instance given if the current value equals the expected value.
+     * </p>
+     * 
+     * @param object A non-null instance of the object with a long field.
+     * @param field A non-null, {@link Long#TYPE} {@link Field} associated with
+     *        <code>object</code>.
+     * @param expectedValue The expected long value of <code>field</code>.
+     * @param newValue The new long to set for <code>field</code>.
+     * @return <code>true</code> if the current value ==
+     *         <code>expectedValue</code> and <code>newValue</code>;
+     *         <code>false</code> if not set.
+     */
+    public abstract boolean compareAndSet(Object object, Field field, long expectedValue,
+            long newValue);
+
+    /**
+     * <p>
+     * Atomically compare and set a long value in the long[] given if the
+     * current value equals the expected value.
+     * </p>
+     * 
+     * @param array The non-null long[] to compare and set into.
+     * @param index The index of the long value to compare and set in
+     *        <code>array</code>.
+     * @param expectedValue The expected long value of the element at
+     *        <code>index</code> in <code>array</code>.
+     * @param newValue The new long value to set for <code>field</code>.
+     * @return <code>true</code> if the current value ==
+     *         <code>expectedValue</code> and <code>newValue</code>;
+     *         <code>false</code> if not set.
+     */
+    public abstract boolean compareAndSet(long[] array, int index, long expectedValue,
+            long newValue);
+
+    /**
+     * <p>
+     * Atomically compare and set an Object reference value on the field of the
+     * object instance given if the current value equals the expected value.
+     * This method only compares references to determine equivalence.
+     * </p>
+     * 
+     * @param object A non-null instance of the object with an Object field.
+     * @param field A non-null, object reference {@link Field} associated with
+     *        <code>object</code>.
+     * @param expectedValue The object reference long value of
+     *        <code>field</code>.
+     * @param newValue The new object reference value to set for
+     *        <code>field</code>.
+     * @return <code>true</code> if the current value ==
+     *         <code>expectedValue</code> and <code>newValue</code>;
+     *         <code>false</code> if not set.
+     */
+    public abstract boolean compareAndSet(Object object, Field field, Object expectedValue,
+            Object newValue);
+
+    /**
+     * <p>
+     * Atomically compare and set an Object reference value in the Object[]
+     * given if the current value equals the expected value. This method only
+     * compares references to determine equivalence.
+     * </p>
+     * 
+     * @param array The non-null Object[] to compare and set into.
+     * @param index The index of the Object reference value to compare and set
+     *        in <code>array</code>.
+     * @param expectedValue The expected Object reference value of the element
+     *        at <code>index</code> in <code>array</code>.
+     * @param newValue The new Object reference value to set for
+     *        <code>field</code>.
+     * @return <code>true</code> if the current value ==
+     *         <code>expectedValue</code> and <code>newValue</code>;
+     *         <code>false</code> if not set.
+     */
+    public abstract boolean compareAndSet(Object[] array, int index, Object expectedValue,
+            Object newValue);
+
+    /**
+     * <p>
+     * Performs a read of an int element from an int[] as though that element
+     * were a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param array The non-null int[] to read from.
+     * @param index The index of the int element to read in <code>array</code>.
+     * @return The int element that was read.
+     */
+    public abstract int volatileGet(int[] array, int index);
+
+    /**
+     * <p>
+     * Performs a write of an int element to an int[] as though that element
+     * were a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param array The non-null int[] to write to.
+     * @param index The index of the int element to write in <code>array</code>.
+     * @param value The int value to write to <code>array</code>.
+     */
+    public abstract void volatileSet(int[] array, int index, int value);
+
+    /**
+     * <p>
+     * Performs a read of a long element from an long[] as though that element
+     * were a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param array The non-null long[] to read from.
+     * @param index The index of the long element to read in <code>array</code>.
+     * @return The long element that was read.
+     */
+    public abstract long volatileGet(long[] array, int index);
+
+    /**
+     * <p>
+     * Performs a write of a long element to an long[] as though that element
+     * were a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param array The non-null long[] to write to.
+     * @param index The index of the long element to write in <code>array</code>.
+     * @param value The long value to write to <code>array</code>.
+     */
+    public abstract void volatileSet(long[] array, int index, long value);
+
+    /**
+     * <p>
+     * Performs a read of an Object reference element from an Object[] as though
+     * that element were a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param array The non-null Object[] to read from.
+     * @param index The index of the Object reference element to read in
+     *        <code>array</code>.
+     * @return The Object reference element that was read.
+     */
+    public abstract Object volatileGet(Object[] array, int index);
+
+    /**
+     * <p>
+     * Performs a write of an Object reference element to an Object[] as though
+     * that element were a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param array The non-null Object[] to write to.
+     * @param index The index of the Object reference element to write in
+     *        <code>array</code>.
+     * @param value The Object reference value to write to <code>array</code>.
+     */
+    public abstract void volatileSet(Object[] array, int index, Object value);
+
+    /**
+     * <p>
+     * Performs a read from an int field on an Object as though that field was a
+     * <code>volatile</code> field.
+     * </p>
+     * 
+     * @param object The non-null Object to read from.
+     * @param field The non-null, {@link Integer#TYPE} {@link Field} of
+     *        <code>object</code> to read.
+     * @return The int value that was read.
+     */
+    public abstract int volatileGetInt(Object object, Field field);
+
+    /**
+     * <p>
+     * Performs a write to an int field on an Object as though that field was a
+     * <code>volatile</code> field.
+     * </p>
+     * 
+     * @param object The non-null Object to write to.
+     * @param field The non-null, {@link Integer#TYPE} {@link Field} of
+     *        <code>object</code> to read.
+     * @param value The int value to write.
+     */
+    public abstract void volatileSetInt(Object object, Field field, int value);
+
+    /**
+     * <p>
+     * Performs a read from an long field on an Object as though that field was
+     * a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param object The non-null Object to read from.
+     * @param field The non-null, {@link Long#TYPE} {@link Field} of
+     *        <code>object</code> to read.
+     * @return The long value that was read.
+     */
+    public abstract long volatileGetLong(Object object, Field field);
+
+    /**
+     * <p>
+     * Performs a write to an long field on an Object as though that field was a
+     * <code>volatile</code> field.
+     * </p>
+     * 
+     * @param object The non-null Object to write to.
+     * @param field The non-null, {@link Integer#TYPE} {@link Field} of
+     *        <code>object</code> to read.
+     * @param value The long value to write.
+     */
+    public abstract void volatileSetLong(Object object, Field field, long value);
+
+    /**
+     * <p>
+     * Performs a read from an Object reference field on an Object as though
+     * that field was a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param object The non-null Object to read from.
+     * @param field The non-null {@link Field} of <code>object</code> to read.
+     * @return The Object reference value that was read.
+     */
+    public abstract Object volatileGetObject(Object object, Field field);
+
+    /**
+     * <p>
+     * Performs a write to an Object reference field on an Object as though that
+     * field was a <code>volatile</code> field.
+     * </p>
+     * 
+     * @param object The non-null Object to write to.
+     * @param field The non-null {@link Field} of <code>object</code> to read.
+     * @param value The Object reference value to write.
+     */
+    public abstract void volatileSetObject(Object object, Field field, Object value);
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/LocksSupport.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/LocksSupport.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/LocksSupport.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/LocksSupport.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,114 @@
+/* Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.concurrent;
+
+/**
+ * <p>
+ * The SPI that VM implementations must implement to provide support for the
+ * <code>java.util.concurrent.locks</code> classes and others. Implementations
+ * of this class are registered as <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">Service
+ * Providers<a> as defined by the <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html">JAR File
+ * Specification</a>. The configuration file for this class has a ClassLoader
+ * resource URI of
+ * <code>META-INF/services/org.apache.harmony.concurrent.LocksSupport</code>.
+ * </p>
+ * 
+ * @see java.util.concurrent.locks
+ */
+public abstract class LocksSupport {
+
+    /*
+     * The implementation is currently just a simple singleton, but can change
+     * in the future.
+     */
+    private static LocksSupport INSTANCE = ServiceLoader.load(LocksSupport.class);
+
+    /**
+     * <p>
+     * Gets an instance of this service provider. See the class documentation
+     * for details on configuring a provider implementation.
+     * </p>
+     * 
+     * @return An instance of LocksSupport.
+     * @throws IllegalStateException if an implementation could not be loaded
+     *         for any reason.
+     */
+    public static LocksSupport getInstance() {
+        if (INSTANCE == null) {
+            throw new IllegalStateException(
+                    "An implementation of LocksSupport could not be loaded.");
+        }
+        return INSTANCE;
+    }
+
+    /**
+     * <p>
+     * All implementations MUST provide a public, nullary constructor.
+     * </p>
+     */
+    protected LocksSupport() {
+        super();
+    }
+
+    /**
+     * <p>
+     * Parks the current thread for maximum amount of time or until interruption
+     * event. See the
+     * {@link java.util.concurrent.locks.LockSupport#parkNanos(long)} method for
+     * details.
+     * </p>
+     * 
+     * @param nanos The maximum number of nanoseconds to park the current
+     *        thread.
+     * @see Thread#currentThread()
+     * @see java.util.concurrent.locks.LockSupport#parkNanos(long)
+     */
+    public abstract void parkNanos(long nanos);
+
+    /**
+     * <p>
+     * Parks the current thread until a specified time or until an interruption
+     * event. See the
+     * {@link java.util.concurrent.locks.LockSupport#parkUntil(long)} method for
+     * details.
+     * </p>
+     * 
+     * @param stopTime The time when the current thread should be unparked. Time
+     *        is defined using the {@link System#currentTimeMillis()}
+     *        definition.
+     * @see Thread#currentThread()
+     * @see System#currentTimeMillis()
+     * @see java.util.concurrent.locks.LockSupport#parkUntil(long)
+     */
+    public abstract void parkUntil(long stopTime);
+
+    /**
+     * <p>
+     * Unparks the Thread passed if it's parked or if not parked guarantees that
+     * the next call to the Thread will not be blocked. See the
+     * {@link java.util.concurrent.locks.LockSupport#unpark(Thread)} method for
+     * details.
+     * </p>
+     * 
+     * @param thread The Thread to unpark; if <code>null</code> or not
+     *        started, then ignore.
+     * 
+     * @see java.util.concurrent.locks.LockSupport#unpark(Thread)
+     */
+    public abstract void unpark(Thread thread);
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/ServiceLoader.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/ServiceLoader.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/ServiceLoader.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/main/java/org/apache/harmony/concurrent/ServiceLoader.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,133 @@
+/* Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.concurrent;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.Enumeration;
+
+/**
+ * <p>
+ * A utility class for loading Service Provider implementations that are
+ * registered using the <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">Service
+ * Providers<a> mechanism defined by the <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html">JAR File
+ * Specification</a>.
+ * </p>
+ */
+class ServiceLoader {
+
+    /**
+     * <p>
+     * Loads a Service Provider for the given interface (SPI).
+     * </p>
+     * 
+     * @param <T> The SPI type.
+     * @param spiClass The class that defines the Service Provider.
+     * @return An instance of an implementation or <code>null</code> if a
+     *         provider couldn't be found or constructed.
+     * @throws NullPointerException if <code>spiClass</code> is
+     *         <code>null</code>.
+     * @throws IllegalArgumentException if <code>spiClass</code> is neither an
+     *         interface nor an abstract class.
+     */
+    static <T> T load(Class<T> spiClass) {
+        if (spiClass == null) {
+            throw new NullPointerException();
+        }
+
+        if (!spiClass.isInterface() || !Modifier.isAbstract(spiClass.getModifiers())) {
+            throw new IllegalArgumentException(
+                    "The SPI class must be an interface or an abstract class.");
+        }
+
+        String spiResURI = "META-INF/services/" + spiClass.getName();
+        ClassLoader classLoader = spiClass.getClassLoader();
+        Enumeration<URL> resources;
+        try {
+            resources = classLoader.getResources(spiResURI);
+        } catch (IOException e) {
+            return null;
+        }
+
+        while (resources.hasMoreElements()) {
+            URL resource = resources.nextElement();
+            BufferedReader reader = null;
+            try {
+                reader = new BufferedReader(new InputStreamReader(resource.openStream()));
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    line = line.trim();
+                    int cmtIdx = line.indexOf('#');
+                    if (cmtIdx != -1) {
+                        line = line.substring(0, cmtIdx);
+                        line = line.trim();
+                    }
+
+                    if (line.length() == 0) {
+                        continue;
+                    }
+
+                    Class<?> implClass;
+                    try {
+                        implClass = classLoader.loadClass(line);
+                    } catch (ClassNotFoundException e) {
+                        // TODO determine how to log this
+                        e.printStackTrace();
+                        continue;
+                    }
+
+                    if (!spiClass.isAssignableFrom(implClass)) {
+                        continue;
+                    }
+
+                    Object impl;
+                    try {
+                        impl = implClass.newInstance();
+                    } catch (Exception e) {
+                        // TODO determine how to log this
+                        e.printStackTrace();
+                        continue;
+                    }
+
+                    // TODO When Class.cast is implemented, use this instead.
+                    // return spi.cast(impl);
+                    return (T) impl;
+                }
+            } catch (IOException e) {
+                // TODO determine how to log this
+                e.printStackTrace();
+                continue;
+            } finally {
+                if (reader != null) {
+                    try {
+                        reader.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private ServiceLoader() {
+    }
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceA.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceA.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceA.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceA.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,19 @@
+/* Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.concurrent;
+
+public interface ServiceA {
+}
\ No newline at end of file

Propchange: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceA.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceAImpl.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceAImpl.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceAImpl.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceAImpl.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,22 @@
+/* Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.concurrent;
+
+public class ServiceAImpl implements ServiceA {
+    public ServiceAImpl() {
+        super();
+    }
+}
\ No newline at end of file

Propchange: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceAImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceLoaderTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceLoaderTest.java?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceLoaderTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceLoaderTest.java Tue Jul 11 21:12:04 2006
@@ -0,0 +1,27 @@
+/* Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.concurrent;
+
+import junit.framework.TestCase;
+
+public class ServiceLoaderTest extends TestCase {
+
+    public void testLoad() {
+        ServiceA sa = ServiceLoader.load(ServiceA.class);
+        assertNotNull(sa);
+        assertEquals(ServiceAImpl.class, sa.getClass());
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/java/org/apache/harmony/concurrent/ServiceLoaderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/resources/META-INF/services/org.apache.harmony.concurrent.ServiceA
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/resources/META-INF/services/org.apache.harmony.concurrent.ServiceA?rev=421111&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/resources/META-INF/services/org.apache.harmony.concurrent.ServiceA (added)
+++ incubator/harmony/enhanced/classlib/trunk/sandbox/juc-proposal/concurrent/src/test/resources/META-INF/services/org.apache.harmony.concurrent.ServiceA Tue Jul 11 21:12:04 2006
@@ -0,0 +1 @@
+org.apache.harmony.concurrent.ServiceAImpl
\ No newline at end of file