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<String, Data> m = new TreeMap<String, Data>();
+ * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+ * private final Lock r = rwl.readLock();
+ * private final Lock w = rwl.writeLock();
+ *
+ * public Data get(String key) {
+ * r.lock(); try { return m.get(key); } finally { r.unlock(); }
+ * }
+ * public String[] allKeys() {
+ * r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); }
+ * }
+ * public Data put(String key, Data value) {
+ * w.lock(); try { return m.put(key, value); } finally { w.unlock(); }
+ * }
+ * public void clear() {
+ * w.lock(); try { m.clear(); } finally { w.unlock(); }
+ * }
+ * }
+ * </pre>
+ *
+ *
+ * <h3>Implementation Notes</h3>
+ *
+ * <p>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 "barging" behavior
+ * can be useful in certain circumstances, even though it
+ * breaks fairness. If you want to honor the fairness setting
+ * for this lock, then use {@link #tryLock(long, TimeUnit)
+ * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
+ * (it also detects interruption).
+ *
+ * <p>If the 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
+ * "Read locks =" followed by the number of held
+ * read locks.
+ * @return a string identifying this lock, as well as its lock state.
+ */
+ public String toString() {
+ int r = sync.getReadLockCount();
+ return super.toString() +
+ "[Read locks = " + r + "]";
+ }
+
+ }
+
+ /**
+ * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
+ */
+ public static class WriteLock implements Lock, java.io.Serializable {
+ private static final long serialVersionUID = -4992448646407690164L;
+ private final Sync sync;
+
+ /**
+ * Constructor for use by subclasses
+ * @param lock the outer lock object
+ * @throws NullPointerException if 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 "barging"
+ * behavior can be useful in certain circumstances, even
+ * though it breaks fairness. If you want to honor the
+ * fairness setting for this lock, then use {@link
+ * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
+ * which is almost equivalent (it also detects interruption).
+ *
+ * <p> If the current thread already holds this lock then the
+ * hold count is incremented by one and the method returns
+ * <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
+ * "Unlocked" or the String "Locked by"
+ * 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 "Write locks ="
+ * follwed by the number of reentrantly held write locks, and the
+ * String "Read locks =" followed by the number of held
+ * read locks.
+ * @return a string identifying this lock, as well as its lock state.
+ */
+ public String toString() {
+ int c = sync.getCount();
+ int w = 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 "best effort" 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