You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by hi...@apache.org on 2009/07/28 11:30:48 UTC
svn commit: r798469 [10/28] - in /harmony/enhanced/classlib/branches/java6:
./ depends/build/platform/ depends/files/ depends/jars/
depends/manifests/icu4j_4.0/ depends/manifests/icu4j_4.2.1/
depends/manifests/icu4j_4.2.1/META-INF/ make/ modules/access...
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/Executors.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/Executors.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/Executors.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/Executors.java Tue Jul 28 09:30:33 2009
@@ -11,6 +11,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
import java.security.AccessControlException;
/**
@@ -18,18 +19,18 @@
* ExecutorService}, {@link ScheduledExecutorService}, {@link
* ThreadFactory}, and {@link Callable} classes defined in this
* package. This class supports the following kinds of methods:
- *
+ *
* <ul>
- * <li> Methods that create and return an {@link ExecutorService}
- * set up with commonly useful configuration settings.
- * <li> Methods that create and return a {@link ScheduledExecutorService}
- * set up with commonly useful configuration settings.
+ * <li> Methods that create and return an {@link ExecutorService}
+ * set up with commonly useful configuration settings.
+ * <li> Methods that create and return a {@link ScheduledExecutorService}
+ * set up with commonly useful configuration settings.
* <li> Methods that create and return a "wrapped" ExecutorService, that
* disables reconfiguration by making implementation-specific methods
* inaccessible.
* <li> Methods that create and return a {@link ThreadFactory}
* that sets newly created threads to a known state.
- * <li> Methods that create and return a {@link Callable}
+ * <li> Methods that create and return a {@link Callable}
* out of other closure-like forms, so they can be used
* in execution methods requiring <tt>Callable</tt>.
* </ul>
@@ -40,14 +41,19 @@
public class Executors {
/**
- * Creates a thread pool that reuses a fixed set of threads
- * operating off a shared unbounded queue. If any thread
- * terminates due to a failure during execution prior to shutdown,
- * a new one will take its place if needed to execute subsequent
- * tasks.
+ * Creates a thread pool that reuses a fixed number of threads
+ * operating off a shared unbounded queue. At any point, at most
+ * <tt>nThreads</tt> threads will be active processing tasks.
+ * If additional tasks are submitted when all threads are active,
+ * they will wait in the queue until a thread is available.
+ * If any thread terminates due to a failure during execution
+ * prior to shutdown, a new one will take its place if needed to
+ * execute subsequent tasks. The threads in the pool will exist
+ * until it is explicitly {@link ExecutorService#shutdown shutdown}.
*
* @param nThreads the number of threads in the pool
* @return the newly created thread pool
+ * @throws IllegalArgumentException if <tt>nThreads <= 0</tt>
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
@@ -56,13 +62,23 @@
}
/**
- * Creates a thread pool that reuses a fixed set of threads
+ * Creates a thread pool that reuses a fixed number of threads
* operating off a shared unbounded queue, using the provided
- * ThreadFactory to create new threads when needed.
+ * ThreadFactory to create new threads when needed. At any point,
+ * at most <tt>nThreads</tt> threads will be active processing
+ * tasks. If additional tasks are submitted when all threads are
+ * active, they will wait in the queue until a thread is
+ * available. If any thread terminates due to a failure during
+ * execution prior to shutdown, a new one will take its place if
+ * needed to execute subsequent tasks. The threads in the pool will
+ * exist until it is explicitly {@link ExecutorService#shutdown
+ * shutdown}.
*
* @param nThreads the number of threads in the pool
* @param threadFactory the factory to use when creating new threads
* @return the newly created thread pool
+ * @throws NullPointerException if threadFactory is null
+ * @throws IllegalArgumentException if <tt>nThreads <= 0</tt>
*/
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
@@ -85,7 +101,7 @@
* @return the newly created single-threaded Executor
*/
public static ExecutorService newSingleThreadExecutor() {
- return new DelegatedExecutorService
+ return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
@@ -95,17 +111,18 @@
* Creates an Executor that uses a single worker thread operating
* off an unbounded queue, and uses the provided ThreadFactory to
* create a new thread when needed. Unlike the otherwise
- * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the returned executor
- * is guaranteed not to be reconfigurable to use additional
- * threads.
- *
+ * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the
+ * returned executor is guaranteed not to be reconfigurable to use
+ * additional threads.
+ *
* @param threadFactory the factory to use when creating new
* threads
*
* @return the newly created single-threaded Executor
+ * @throws NullPointerException if threadFactory is null
*/
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
- return new DelegatedExecutorService
+ return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
@@ -141,6 +158,7 @@
* ThreadFactory to create new threads when needed.
* @param threadFactory the factory to use when creating new threads
* @return the newly created thread pool
+ * @throws NullPointerException if threadFactory is null
*/
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
@@ -148,7 +166,7 @@
new SynchronousQueue<Runnable>(),
threadFactory);
}
-
+
/**
* Creates a single-threaded executor that can schedule commands
* to run after a given delay, or to execute periodically.
@@ -181,31 +199,35 @@
* @param threadFactory the factory to use when creating new
* threads
* @return a newly created scheduled executor
+ * @throws NullPointerException if threadFactory is null
*/
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}
-
+
/**
- * Creates a thread pool that can schedule commands to run after a
+ * Creates a thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle.
* @return a newly created scheduled thread pool
+ * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt>
*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
/**
- * Creates a thread pool that can schedule commands to run after a
+ * Creates a thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle.
* @param threadFactory the factory to use when the executor
- * creates a new thread.
+ * creates a new thread.
* @return a newly created scheduled thread pool
+ * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt>
+ * @throws NullPointerException if threadFactory is null
*/
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
@@ -244,7 +266,7 @@
throw new NullPointerException();
return new DelegatedScheduledExecutorService(executor);
}
-
+
/**
* Returns a default thread factory used to create new threads.
* This factory creates all new threads used by an Executor in the
@@ -252,8 +274,9 @@
* java.lang.SecurityManager}, it uses the group of {@link
* System#getSecurityManager}, else the group of the thread
* invoking this <tt>defaultThreadFactory</tt> method. Each new
- * thread is created as a non-daemon thread with priority
- * <tt>Thread.NORM_PRIORITY</tt>. New threads have names
+ * thread is created as a non-daemon thread with priority set to
+ * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum
+ * priority permitted in the thread group. New threads have names
* accessible via {@link Thread#getName} of
* <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
* number of this factory, and <em>M</em> is the sequence number
@@ -307,8 +330,8 @@
* <tt>Callable</tt> to an otherwise resultless action.
* @param task the task to run
* @param result the result to return
- * @throws NullPointerException if task null
* @return a callable object
+ * @throws NullPointerException if task null
*/
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
@@ -336,10 +359,11 @@
* @return a callable object
* @throws NullPointerException if action null
*/
- public static Callable<Object> callable(PrivilegedAction action) {
+ public static Callable<Object> callable(final PrivilegedAction<?> action) {
if (action == null)
throw new NullPointerException();
- return new PrivilegedActionAdapter(action);
+ return new Callable<Object>() {
+ public Object call() { return action.run(); }};
}
/**
@@ -350,10 +374,11 @@
* @return a callable object
* @throws NullPointerException if action null
*/
- public static Callable<Object> callable(PrivilegedExceptionAction action) {
+ public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
if (action == null)
throw new NullPointerException();
- return new PrivilegedExceptionActionAdapter(action);
+ return new Callable<Object>() {
+ public Object call() throws Exception { return action.run(); }};
}
/**
@@ -373,9 +398,9 @@
public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
if (callable == null)
throw new NullPointerException();
- return new PrivilegedCallable(callable);
+ return new PrivilegedCallable<T>(callable);
}
-
+
/**
* Returns a {@link Callable} object that will, when
* called, execute the given <tt>callable</tt> under the current
@@ -397,7 +422,7 @@
public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
if (callable == null)
throw new NullPointerException();
- return new PrivilegedCallableUsingCurrentClassLoader(callable);
+ return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
}
// Non-public classes supporting the public methods
@@ -408,71 +433,39 @@
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
- RunnableAdapter(Runnable task, T result) {
- this.task = task;
+ RunnableAdapter(Runnable task, T result) {
+ this.task = task;
this.result = result;
}
- public T call() {
- task.run();
- return result;
- }
- }
-
- /**
- * A callable that runs given privileged action and returns its result
- */
- static final class PrivilegedActionAdapter implements Callable<Object> {
- PrivilegedActionAdapter(PrivilegedAction action) {
- this.action = action;
- }
- public Object call () {
- return action.run();
- }
- private final PrivilegedAction action;
- }
-
- /**
- * A callable that runs given privileged exception action and returns its result
- */
- static final class PrivilegedExceptionActionAdapter implements Callable<Object> {
- PrivilegedExceptionActionAdapter(PrivilegedExceptionAction action) {
- this.action = action;
- }
- public Object call () throws Exception {
- return action.run();
+ public T call() {
+ task.run();
+ return result;
}
- private final PrivilegedExceptionAction action;
}
-
/**
* A callable that runs under established access control settings
*/
static final class PrivilegedCallable<T> implements Callable<T> {
- private final AccessControlContext acc;
private final Callable<T> task;
- private T result;
- private Exception exception;
+ private final AccessControlContext acc;
+
PrivilegedCallable(Callable<T> task) {
this.task = task;
this.acc = AccessController.getContext();
}
public T call() throws Exception {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- try {
- result = task.call();
- } catch(Exception ex) {
- exception = ex;
+ try {
+ return AccessController.doPrivileged(
+ new PrivilegedExceptionAction<T>() {
+ public T run() throws Exception {
+ return task.call();
}
- return null;
- }
- }, acc);
- if (exception != null)
- throw exception;
- else
- return result;
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
}
}
@@ -481,44 +474,50 @@
* current ClassLoader
*/
static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
- private final ClassLoader ccl;
- private final AccessControlContext acc;
private final Callable<T> task;
- private T result;
- private Exception exception;
+ private final AccessControlContext acc;
+ private final ClassLoader ccl;
+
PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ // Calls to getContextClassLoader from this class
+ // never trigger a security check, but we check
+ // whether our callers have this permission anyways.
+ sm.checkPermission(new RuntimePermission("getContextClassLoader"));
+
+ // Whether setContextClassLoader turns out to be necessary
+ // or not, we fail fast if permission is not available.
+ sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ }
this.task = task;
- this.ccl = Thread.currentThread().getContextClassLoader();
this.acc = AccessController.getContext();
- acc.checkPermission(new RuntimePermission("getContextClassLoader"));
- acc.checkPermission(new RuntimePermission("setContextClassLoader"));
+ this.ccl = Thread.currentThread().getContextClassLoader();
}
public T call() throws Exception {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- ClassLoader savedcl = null;
- Thread t = Thread.currentThread();
- try {
- ClassLoader cl = t.getContextClassLoader();
- if (ccl != cl) {
- t.setContextClassLoader(ccl);
- savedcl = cl;
+ try {
+ return AccessController.doPrivileged(
+ new PrivilegedExceptionAction<T>() {
+ public T run() throws Exception {
+ ClassLoader savedcl = null;
+ Thread t = Thread.currentThread();
+ try {
+ ClassLoader cl = t.getContextClassLoader();
+ if (ccl != cl) {
+ t.setContextClassLoader(ccl);
+ savedcl = cl;
+ }
+ return task.call();
+ } finally {
+ if (savedcl != null)
+ t.setContextClassLoader(savedcl);
}
- result = task.call();
- } catch(Exception ex) {
- exception = ex;
- } finally {
- if (savedcl != null)
- t.setContextClassLoader(savedcl);
}
- return null;
- }
- }, acc);
- if (exception != null)
- throw exception;
- else
- return result;
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
}
}
@@ -526,22 +525,22 @@
* The default thread factory
*/
static class DefaultThreadFactory implements ThreadFactory {
- static final AtomicInteger poolNumber = new AtomicInteger(1);
- final ThreadGroup group;
- final AtomicInteger threadNumber = new AtomicInteger(1);
- final String namePrefix;
+ private static final AtomicInteger poolNumber = new AtomicInteger(1);
+ private final ThreadGroup group;
+ private final AtomicInteger threadNumber = new AtomicInteger(1);
+ private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null)? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
- namePrefix = "pool-" +
- poolNumber.getAndIncrement() +
+ namePrefix = "pool-" +
+ poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
- Thread t = new Thread(group, r,
+ Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
@@ -553,38 +552,46 @@
}
/**
- * Thread factory capturing access control and class loader
+ * Thread factory capturing access control context and class loader
*/
static class PrivilegedThreadFactory extends DefaultThreadFactory {
- private final ClassLoader ccl;
private final AccessControlContext acc;
+ private final ClassLoader ccl;
PrivilegedThreadFactory() {
super();
- this.ccl = Thread.currentThread().getContextClassLoader();
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ // Calls to getContextClassLoader from this class
+ // never trigger a security check, but we check
+ // whether our callers have this permission anyways.
+ sm.checkPermission(new RuntimePermission("getContextClassLoader"));
+
+ // Fail fast
+ sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ }
this.acc = AccessController.getContext();
- acc.checkPermission(new RuntimePermission("setContextClassLoader"));
+ this.ccl = Thread.currentThread().getContextClassLoader();
}
-
+
public Thread newThread(final Runnable r) {
return super.newThread(new Runnable() {
public void run() {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
Thread.currentThread().setContextClassLoader(ccl);
r.run();
- return null;
+ return null;
}
}, acc);
}
});
}
-
}
- /**
+ /**
* A wrapper class that exposes only the ExecutorService methods
- * of an implementation.
+ * of an ExecutorService implementation.
*/
static class DelegatedExecutorService extends AbstractExecutorService {
private final ExecutorService e;
@@ -611,8 +618,8 @@
throws InterruptedException {
return e.invokeAll(tasks);
}
- public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
- long timeout, TimeUnit unit)
+ public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit)
throws InterruptedException {
return e.invokeAll(tasks, timeout, unit);
}
@@ -620,19 +627,29 @@
throws InterruptedException, ExecutionException {
return e.invokeAny(tasks);
}
- public <T> T invokeAny(Collection<Callable<T>> tasks,
- long timeout, TimeUnit unit)
+ public <T> T invokeAny(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return e.invokeAny(tasks, timeout, unit);
}
}
-
+
+ static class FinalizableDelegatedExecutorService
+ extends DelegatedExecutorService {
+ FinalizableDelegatedExecutorService(ExecutorService executor) {
+ super(executor);
+ }
+ protected void finalize() {
+ super.shutdown();
+ }
+ }
+
/**
- * A wrapper class that exposes only the ExecutorService and
- * ScheduleExecutor methods of a ScheduledExecutorService implementation.
+ * A wrapper class that exposes only the ScheduledExecutorService
+ * methods of a ScheduledExecutorService implementation.
*/
static class DelegatedScheduledExecutorService
- extends DelegatedExecutorService
+ extends DelegatedExecutorService
implements ScheduledExecutorService {
private final ScheduledExecutorService e;
DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
@@ -653,7 +670,7 @@
}
}
-
+
/** Cannot instantiate. */
private Executors() {}
}
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/Future.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/Future.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/Future.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/Future.java Tue Jul 28 09:30:33 2009
@@ -29,10 +29,13 @@
* class App {
* ExecutorService executor = ...
* ArchiveSearcher searcher = ...
- * void showSearch(final String target) throws InterruptedException {
- * Future<String> future = executor.submit(new Callable<String>() {
- * public String call() { return searcher.search(target); }
- * });
+ * void showSearch(final String target)
+ * throws InterruptedException {
+ * Future<String> future
+ * = executor.submit(new Callable<String>() {
+ * public String call() {
+ * return searcher.search(target);
+ * }});
* displayOtherThings(); // do other things while searching
* try {
* displayText(future.get()); // use future
@@ -41,8 +44,8 @@
* }
* </pre>
*
- * The {@link FutureTask} class is an implementation of <tt>Future</tt> that
- * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
+ * The {@link FutureTask} class is an implementation of <tt>Future</tt> that
+ * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
* For example, the above construction with <tt>submit</tt> could be replaced by:
* <pre>
* FutureTask<String> future =
@@ -52,6 +55,11 @@
* }});
* executor.execute(future);
* </pre>
+ *
+ * <p>Memory consistency effects: Actions taken by the asynchronous computation
+ * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
+ * actions following the corresponding {@code Future.get()} in another thread.
+ *
* @see FutureTask
* @see Executor
* @since 1.5
@@ -62,7 +70,7 @@
/**
* Attempts to cancel execution of this task. This attempt will
- * fail if the task has already completed, already been cancelled,
+ * fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when <tt>cancel</tt> is called,
* this task should never run. If the task has already started,
@@ -70,6 +78,10 @@
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.
*
+ * <p>After this method returns, subsequent calls to {@link #isDone} will
+ * always return <tt>true</tt>. Subsequent calls to {@link #isCancelled}
+ * will always return <tt>true</tt> if this method returned <tt>true</tt>.
+ *
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete
@@ -83,18 +95,18 @@
* Returns <tt>true</tt> if this task was cancelled before it completed
* normally.
*
- * @return <tt>true</tt> if task was cancelled before it completed
+ * @return <tt>true</tt> if this task was cancelled before it completed
*/
boolean isCancelled();
/**
- * Returns <tt>true</tt> if this task completed.
+ * Returns <tt>true</tt> if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* <tt>true</tt>.
- *
- * @return <tt>true</tt> if this task completed.
+ *
+ * @return <tt>true</tt> if this task completed
*/
boolean isDone();
@@ -128,6 +140,3 @@
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
-
-
-
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/FutureTask.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/FutureTask.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/FutureTask.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/FutureTask.java Tue Jul 28 09:30:33 2009
@@ -35,7 +35,7 @@
private final Sync sync;
/**
- * Creates a <tt>FutureTask</tt> that will upon running, execute the
+ * Creates a <tt>FutureTask</tt> that will, upon running, execute the
* given <tt>Callable</tt>.
*
* @param callable the callable task
@@ -48,11 +48,11 @@
}
/**
- * Creates a <tt>FutureTask</tt> that will upon running, execute the
+ * Creates a <tt>FutureTask</tt> that will, upon running, execute the
* given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
* given result on successful completion.
*
- * @param runnable the runnable task
+ * @param runnable the runnable task
* @param result the result to return on successful completion. If
* you don't need a particular result, consider using
* constructions of the form:
@@ -66,7 +66,7 @@
public boolean isCancelled() {
return sync.innerIsCancelled();
}
-
+
public boolean isDone() {
return sync.innerIsDone();
}
@@ -74,11 +74,17 @@
public boolean cancel(boolean mayInterruptIfRunning) {
return sync.innerCancel(mayInterruptIfRunning);
}
-
+
+ /**
+ * @throws CancellationException {@inheritDoc}
+ */
public V get() throws InterruptedException, ExecutionException {
return sync.innerGet();
}
+ /**
+ * @throws CancellationException {@inheritDoc}
+ */
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return sync.innerGet(unit.toNanos(timeout));
@@ -98,8 +104,10 @@
/**
* Sets the result of this Future to the given value unless
* this future has already been set or has been cancelled.
+ * This method is invoked internally by the <tt>run</tt> method
+ * upon successful completion of the computation.
* @param v the value
- */
+ */
protected void set(V v) {
sync.innerSet(v);
}
@@ -108,15 +116,22 @@
* Causes this future to report an <tt>ExecutionException</tt>
* with the given throwable as its cause, unless this Future has
* already been set or has been cancelled.
- * @param t the cause of failure.
- */
+ * This method is invoked internally by the <tt>run</tt> method
+ * upon failure of the computation.
+ * @param t the cause of failure
+ */
protected void setException(Throwable t) {
sync.innerSetException(t);
}
-
+
+ // The following (duplicated) doc comment can be removed once
+ //
+ // 6270645: Javadoc comments should be inherited from most derived
+ // superinterface or superclass
+ // is fixed.
/**
- * Sets this Future to the result of computation unless
- * it has been cancelled.
+ * Sets this Future to the result of its computation
+ * unless it has been cancelled.
*/
public void run() {
sync.innerRun();
@@ -143,6 +158,10 @@
* Uses AQS sync state to represent run status
*/
private final class Sync extends AbstractQueuedSynchronizer {
+ private static final long serialVersionUID = -7828117401763700385L;
+
+ /** State value representing that task is ready to run */
+ private static final int READY = 0;
/** State value representing that task is running */
private static final int RUNNING = 1;
/** State value representing that task ran */
@@ -157,10 +176,10 @@
/** The exception to throw from get() */
private Throwable exception;
- /**
+ /**
* The thread running task. When nulled after set/cancel, this
* indicates that the results are accessible. Must be
- * volatile, to serve as write barrier on completion.
+ * volatile, to ensure visibility upon completion.
*/
private volatile Thread runner;
@@ -176,7 +195,7 @@
* Implements AQS base acquire to succeed if ran or cancelled
*/
protected int tryAcquireShared(int ignore) {
- return innerIsDone()? 1 : -1;
+ return innerIsDone() ? 1 : -1;
}
/**
@@ -185,13 +204,13 @@
*/
protected boolean tryReleaseShared(int ignore) {
runner = null;
- return true;
+ return true;
}
boolean innerIsCancelled() {
return getState() == CANCELLED;
}
-
+
boolean innerIsDone() {
return ranOrCancelled(getState()) && runner == null;
}
@@ -207,7 +226,7 @@
V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
if (!tryAcquireSharedNanos(0, nanosTimeout))
- throw new TimeoutException();
+ throw new TimeoutException();
if (getState() == CANCELLED)
throw new CancellationException();
if (exception != null)
@@ -216,28 +235,55 @@
}
void innerSet(V v) {
- int s = getState();
- if (ranOrCancelled(s) || !compareAndSetState(s, RAN))
- return;
- result = v;
- releaseShared(0);
- done();
+ for (;;) {
+ int s = getState();
+ if (s == RAN)
+ return;
+ if (s == CANCELLED) {
+ // aggressively release to set runner to null,
+ // in case we are racing with a cancel request
+ // that will try to interrupt runner
+ releaseShared(0);
+ return;
+ }
+ if (compareAndSetState(s, RAN)) {
+ result = v;
+ releaseShared(0);
+ done();
+ return;
+ }
+ }
}
void innerSetException(Throwable t) {
- int s = getState();
- if (ranOrCancelled(s) || !compareAndSetState(s, RAN))
- return;
- exception = t;
- result = null;
- releaseShared(0);
- done();
+ for (;;) {
+ int s = getState();
+ if (s == RAN)
+ return;
+ if (s == CANCELLED) {
+ // aggressively release to set runner to null,
+ // in case we are racing with a cancel request
+ // that will try to interrupt runner
+ releaseShared(0);
+ return;
+ }
+ if (compareAndSetState(s, RAN)) {
+ exception = t;
+ releaseShared(0);
+ done();
+ return;
+ }
+ }
}
boolean innerCancel(boolean mayInterruptIfRunning) {
- int s = getState();
- if (ranOrCancelled(s) || !compareAndSetState(s, CANCELLED))
- return false;
+ for (;;) {
+ int s = getState();
+ if (ranOrCancelled(s))
+ return false;
+ if (compareAndSetState(s, CANCELLED))
+ break;
+ }
if (mayInterruptIfRunning) {
Thread r = runner;
if (r != null)
@@ -249,28 +295,37 @@
}
void innerRun() {
- if (!compareAndSetState(0, RUNNING))
+ if (!compareAndSetState(READY, RUNNING))
return;
- try {
- runner = Thread.currentThread();
- innerSet(callable.call());
- } catch(Throwable ex) {
- innerSetException(ex);
- }
+
+ runner = Thread.currentThread();
+ if (getState() == RUNNING) { // recheck after setting thread
+ V result;
+ try {
+ result = callable.call();
+ } catch (Throwable ex) {
+ setException(ex);
+ return;
+ }
+ set(result);
+ } else {
+ releaseShared(0); // cancel
+ }
}
boolean innerRunAndReset() {
- if (!compareAndSetState(0, RUNNING))
+ if (!compareAndSetState(READY, RUNNING))
return false;
try {
runner = Thread.currentThread();
- callable.call(); // don't set result
+ if (getState() == RUNNING)
+ callable.call(); // don't set result
runner = null;
- return compareAndSetState(RUNNING, 0);
- } catch(Throwable ex) {
- innerSetException(ex);
+ return compareAndSetState(RUNNING, READY);
+ } catch (Throwable ex) {
+ setException(ex);
return false;
- }
+ }
}
}
}
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java Tue Jul 28 09:30:33 2009
@@ -28,18 +28,19 @@
* dynamically created upon each insertion unless this would bring the
* queue above capacity.
*
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Collection} and {@link Iterator} interfaces.
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
*
* <p>This class is a member of the
- * <a href="{@docRoot}/../guide/collections/index.html">
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @since 1.5
* @author Doug Lea
* @param <E> the type of elements held in this collection
*
- **/
+ */
public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
private static final long serialVersionUID = -6903933977591709194L;
@@ -56,7 +57,7 @@
* items have been entered since the signal. And symmetrically for
* takes signalling puts. Operations such as remove(Object) and
* iterators acquire both locks.
- */
+ */
/**
* Linked list node class
@@ -93,7 +94,7 @@
private final Condition notFull = putLock.newCondition();
/**
- * Signal a waiting take. Called only from put/offer (which do not
+ * Signals a waiting take. Called only from put/offer (which do not
* otherwise ordinarily lock takeLock.)
*/
private void signalNotEmpty() {
@@ -107,7 +108,7 @@
}
/**
- * Signal a waiting put. Called only from take/poll.
+ * Signals a waiting put. Called only from take/poll.
*/
private void signalNotFull() {
final ReentrantLock putLock = this.putLock;
@@ -120,7 +121,7 @@
}
/**
- * Create a node and link it at end of queue
+ * Creates a node and links it at end of queue.
* @param x the item
*/
private void insert(E x) {
@@ -128,11 +129,13 @@
}
/**
- * Remove a node from head of queue,
+ * Removes a node from head of queue,
* @return the node
*/
private E extract() {
- Node<E> first = head.next;
+ Node<E> h = head;
+ Node<E> first = h.next;
+ h.next = null; // help GC
head = first;
E x = first.item;
first.item = null;
@@ -167,9 +170,9 @@
/**
* Creates a <tt>LinkedBlockingQueue</tt> with the given (fixed) capacity.
*
- * @param capacity the capacity of this queue.
+ * @param capacity the capacity of this queue
* @throws IllegalArgumentException if <tt>capacity</tt> is not greater
- * than zero.
+ * than zero
*/
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
@@ -182,14 +185,15 @@
* {@link Integer#MAX_VALUE}, initially containing the elements of the
* given collection,
* added in traversal order of the collection's iterator.
+ *
* @param c the collection of elements to initially contain
- * @throws NullPointerException if <tt>c</tt> or any element within it
- * is <tt>null</tt>
+ * @throws NullPointerException if the specified collection or any
+ * of its elements are null
*/
public LinkedBlockingQueue(Collection<? extends E> c) {
this(Integer.MAX_VALUE);
- for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
- add(it.next());
+ for (E e : c)
+ add(e);
}
@@ -198,7 +202,7 @@
/**
* Returns the number of elements in this queue.
*
- * @return the number of elements in this queue.
+ * @return the number of elements in this queue
*/
public int size() {
return count.get();
@@ -207,31 +211,29 @@
// this doc comment is a modified copy of the inherited doc comment,
// without the reference to unlimited queues.
/**
- * Returns the number of elements that this queue can ideally (in
- * the absence of memory or resource constraints) accept without
+ * Returns the number of additional elements that this queue can ideally
+ * (in the absence of memory or resource constraints) accept without
* blocking. This is always equal to the initial capacity of this queue
* less the current <tt>size</tt> of this queue.
- * <p>Note that you <em>cannot</em> always tell if
- * an attempt to <tt>add</tt> an element will succeed by
- * inspecting <tt>remainingCapacity</tt> because it may be the
- * case that a waiting consumer is ready to <tt>take</tt> an
- * element out of an otherwise full queue.
*
- * @return the remaining capacity
+ * <p>Note that you <em>cannot</em> always tell if an attempt to insert
+ * an element will succeed by inspecting <tt>remainingCapacity</tt>
+ * because it may be the case that another thread is about to
+ * insert or remove an element.
*/
public int remainingCapacity() {
return capacity - count.get();
}
/**
- * Adds the specified element to the tail of this queue, waiting if
+ * Inserts the specified element at the tail of this queue, waiting if
* necessary for space to become available.
- * @param o the element to add
- * @throws InterruptedException if interrupted while waiting.
- * @throws NullPointerException if the specified element is <tt>null</tt>.
+ *
+ * @throws InterruptedException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
*/
- public void put(E o) throws InterruptedException {
- if (o == null) throw new NullPointerException();
+ public void put(E e) throws InterruptedException {
+ if (e == null) throw new NullPointerException();
// Note: convention in all put/take/etc is to preset
// local var holding count negative to indicate failure unless set.
int c = -1;
@@ -255,7 +257,7 @@
notFull.signal(); // propagate to a non-interrupted thread
throw ie;
}
- insert(o);
+ insert(e);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
@@ -269,20 +271,16 @@
/**
* Inserts the specified element at the tail of this queue, waiting if
* necessary up to the specified wait time for space to become available.
- * @param o the element to add
- * @param timeout how long to wait before giving up, in units of
- * <tt>unit</tt>
- * @param unit a <tt>TimeUnit</tt> determining how to interpret the
- * <tt>timeout</tt> parameter
+ *
* @return <tt>true</tt> if successful, or <tt>false</tt> if
- * the specified waiting time elapses before space is available.
- * @throws InterruptedException if interrupted while waiting.
- * @throws NullPointerException if the specified element is <tt>null</tt>.
+ * the specified waiting time elapses before space is available.
+ * @throws InterruptedException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
*/
- public boolean offer(E o, long timeout, TimeUnit unit)
+ public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException {
- if (o == null) throw new NullPointerException();
+ if (e == null) throw new NullPointerException();
long nanos = unit.toNanos(timeout);
int c = -1;
final ReentrantLock putLock = this.putLock;
@@ -291,7 +289,7 @@
try {
for (;;) {
if (count.get() < capacity) {
- insert(o);
+ insert(e);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
@@ -315,16 +313,18 @@
}
/**
- * Inserts the specified element at the tail of this queue if possible,
- * returning immediately if this queue is full.
+ * Inserts the specified element at the tail of this queue if it is
+ * possible to do so immediately without exceeding the queue's capacity,
+ * returning <tt>true</tt> upon success and <tt>false</tt> if this queue
+ * is full.
+ * When using a capacity-restricted queue, this method is generally
+ * preferable to method {@link BlockingQueue#add add}, which can fail to
+ * insert an element only by throwing an exception.
*
- * @param o the element to add.
- * @return <tt>true</tt> if it was possible to add the element to
- * this queue, else <tt>false</tt>
- * @throws NullPointerException if the specified element is <tt>null</tt>
+ * @throws NullPointerException if the specified element is null
*/
- public boolean offer(E o) {
- if (o == null) throw new NullPointerException();
+ public boolean offer(E e) {
+ if (e == null) throw new NullPointerException();
final AtomicInteger count = this.count;
if (count.get() == capacity)
return false;
@@ -333,7 +333,7 @@
putLock.lock();
try {
if (count.get() < capacity) {
- insert(o);
+ insert(e);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
@@ -447,6 +447,17 @@
}
}
+ /**
+ * Removes a single instance of the specified element from this queue,
+ * if it is present. More formally, removes an element <tt>e</tt> such
+ * that <tt>o.equals(e)</tt>, if this queue contains one or more such
+ * elements.
+ * Returns <tt>true</tt> if this queue contained the specified element
+ * (or equivalently, if this queue changed as a result of the call).
+ *
+ * @param o element to be removed from this queue, if present
+ * @return <tt>true</tt> if this queue changed as a result of the call
+ */
public boolean remove(Object o) {
if (o == null) return false;
boolean removed = false;
@@ -465,6 +476,8 @@
if (removed) {
p.item = null;
trail.next = p.next;
+ if (last == p)
+ last = trail;
if (count.getAndDecrement() == capacity)
notFull.signalAll();
}
@@ -474,6 +487,19 @@
return removed;
}
+ /**
+ * Returns an array containing all of the elements in this queue, in
+ * proper sequence.
+ *
+ * <p>The returned array will be "safe" in that no references to it are
+ * maintained by this queue. (In other words, this method must allocate
+ * a new array). The caller is thus free to modify the returned array.
+ *
+ * <p>This method acts as bridge between array-based and collection-based
+ * APIs.
+ *
+ * @return an array containing all of the elements in this queue
+ */
public Object[] toArray() {
fullyLock();
try {
@@ -488,6 +514,42 @@
}
}
+ /**
+ * Returns an array containing all of the elements in this queue, in
+ * proper sequence; the runtime type of the returned array is that of
+ * the specified array. If the queue fits in the specified array, it
+ * is returned therein. Otherwise, a new array is allocated with the
+ * runtime type of the specified array and the size of this queue.
+ *
+ * <p>If this queue fits in the specified array with room to spare
+ * (i.e., the array has more elements than this queue), the element in
+ * the array immediately following the end of the queue is set to
+ * <tt>null</tt>.
+ *
+ * <p>Like the {@link #toArray()} method, this method acts as bridge between
+ * array-based and collection-based APIs. Further, this method allows
+ * precise control over the runtime type of the output array, and may,
+ * under certain circumstances, be used to save allocation costs.
+ *
+ * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
+ * The following code can be used to dump the queue into a newly
+ * allocated array of <tt>String</tt>:
+ *
+ * <pre>
+ * String[] y = x.toArray(new String[0]);</pre>
+ *
+ * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+ * <tt>toArray()</tt>.
+ *
+ * @param a the array into which the elements of the queue are to
+ * be stored, if it is big enough; otherwise, a new array of the
+ * same runtime type is allocated for this purpose
+ * @return an array containing all of the elements in this queue
+ * @throws ArrayStoreException if the runtime type of the specified array
+ * is not a supertype of the runtime type of every element in
+ * this queue
+ * @throws NullPointerException if the specified array is null
+ */
public <T> T[] toArray(T[] a) {
fullyLock();
try {
@@ -499,6 +561,8 @@
int k = 0;
for (Node p = head.next; p != null; p = p.next)
a[k++] = (T)p.item;
+ if (a.length > k)
+ a[k] = null;
return a;
} finally {
fullyUnlock();
@@ -514,10 +578,16 @@
}
}
+ /**
+ * Atomically removes all of the elements from this queue.
+ * The queue will be empty after this call returns.
+ */
public void clear() {
fullyLock();
try {
head.next = null;
+ assert head.item == null;
+ last = head;
if (count.getAndSet(0) == capacity)
notFull.signalAll();
} finally {
@@ -525,16 +595,24 @@
}
}
+ /**
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
public int drainTo(Collection<? super E> c) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
- Node first;
+ Node<E> first;
fullyLock();
try {
first = head.next;
head.next = null;
+ assert head.item == null;
+ last = head;
if (count.getAndSet(0) == capacity)
notFull.signalAll();
} finally {
@@ -549,14 +627,18 @@
}
return n;
}
-
+
+ /**
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
public int drainTo(Collection<? super E> c, int maxElements) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
- if (maxElements <= 0)
- return 0;
fullyLock();
try {
int n = 0;
@@ -569,6 +651,9 @@
}
if (n != 0) {
head.next = p;
+ assert head.item == null;
+ if (p == null)
+ last = head;
if (count.getAndAdd(-n) == capacity)
notFull.signalAll();
}
@@ -581,12 +666,12 @@
/**
* Returns an iterator over the elements in this queue in proper sequence.
* The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException},
+ * will never throw {@link ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
* reflect any modifications subsequent to construction.
*
- * @return an iterator over the elements in this queue in proper sequence.
+ * @return an iterator over the elements in this queue in proper sequence
*/
public Iterator<E> iterator() {
return new Itr();
@@ -660,6 +745,8 @@
if (p == node) {
p.item = null;
trail.next = p.next;
+ if (last == p)
+ last = trail;
int c = count.getAndDecrement();
if (c == capacity)
notFull.signalAll();
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java Tue Jul 28 09:30:33 2009
@@ -15,19 +15,50 @@
* blocking retrieval operations. While this queue is logically
* unbounded, attempted additions may fail due to resource exhaustion
* (causing <tt>OutOfMemoryError</tt>). This class does not permit
- * <tt>null</tt> elements. A priority queue relying on natural
- * ordering also does not permit insertion of non-comparable objects
- * (doing so results in <tt>ClassCastException</tt>).
+ * <tt>null</tt> elements. A priority queue relying on {@linkplain
+ * Comparable natural ordering} also does not permit insertion of
+ * non-comparable objects (doing so results in
+ * <tt>ClassCastException</tt>).
*
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Collection} and {@link Iterator} interfaces.
- * <p>The Iterator provided in method {@link #iterator()} is
- * <em>not</em> guaranteed to traverse the elements of the
- * PriorityBlockingQueue in any particular order. If you need ordered
- * traversal, consider using <tt>Arrays.sort(pq.toArray())</tt>.
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces. The Iterator provided in method {@link
+ * #iterator()} is <em>not</em> guaranteed to traverse the elements of
+ * the PriorityBlockingQueue in any particular order. If you need
+ * ordered traversal, consider using
+ * <tt>Arrays.sort(pq.toArray())</tt>. Also, method <tt>drainTo</tt>
+ * can be used to <em>remove</em> some or all elements in priority
+ * order and place them in another collection.
+ *
+ * <p>Operations on this class make no guarantees about the ordering
+ * of elements with equal priority. If you need to enforce an
+ * ordering, you can define custom classes or comparators that use a
+ * secondary key to break ties in primary priority values. For
+ * example, here is a class that applies first-in-first-out
+ * tie-breaking to comparable elements. To use it, you would insert a
+ * <tt>new FIFOEntry(anEntry)</tt> instead of a plain entry object.
+ *
+ * <pre>
+ * class FIFOEntry<E extends Comparable<? super E>>
+ * implements Comparable<FIFOEntry<E>> {
+ * final static AtomicLong seq = new AtomicLong();
+ * final long seqNum;
+ * final E entry;
+ * public FIFOEntry(E entry) {
+ * seqNum = seq.getAndIncrement();
+ * this.entry = entry;
+ * }
+ * public E getEntry() { return entry; }
+ * public int compareTo(FIFOEntry<E> other) {
+ * int res = entry.compareTo(other.entry);
+ * if (res == 0 && other.entry != this.entry)
+ * res = (seqNum < other.seqNum ? -1 : 1);
+ * return res;
+ * }
+ * }</pre>
*
* <p>This class is a member of the
- * <a href="{@docRoot}/../guide/collections/index.html">
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @since 1.5
@@ -43,24 +74,22 @@
private final Condition notEmpty = lock.newCondition();
/**
- * Creates a <tt>PriorityBlockingQueue</tt> with the default initial
- * capacity
- * (11) that orders its elements according to their natural
- * ordering (using <tt>Comparable</tt>).
+ * Creates a <tt>PriorityBlockingQueue</tt> with the default
+ * initial capacity (11) that orders its elements according to
+ * their {@linkplain Comparable natural ordering}.
*/
public PriorityBlockingQueue() {
q = new PriorityQueue<E>();
}
/**
- * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
- * capacity
- * that orders its elements according to their natural ordering
- * (using <tt>Comparable</tt>).
+ * Creates a <tt>PriorityBlockingQueue</tt> with the specified
+ * initial capacity that orders its elements according to their
+ * {@linkplain Comparable natural ordering}.
*
- * @param initialCapacity the initial capacity for this priority queue.
+ * @param initialCapacity the initial capacity for this priority queue
* @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
- * than 1
+ * than 1
*/
public PriorityBlockingQueue(int initialCapacity) {
q = new PriorityQueue<E>(initialCapacity, null);
@@ -68,15 +97,15 @@
/**
* Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
- * capacity
- * that orders its elements according to the specified comparator.
+ * capacity that orders its elements according to the specified
+ * comparator.
*
- * @param initialCapacity the initial capacity for this priority queue.
- * @param comparator the comparator used to order this priority queue.
- * If <tt>null</tt> then the order depends on the elements' natural
- * ordering.
+ * @param initialCapacity the initial capacity for this priority queue
+ * @param comparator the comparator that will be used to order this
+ * priority queue. If {@code null}, the {@linkplain Comparable
+ * natural ordering} of the elements will be used.
* @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
- * than 1
+ * than 1
*/
public PriorityBlockingQueue(int initialCapacity,
Comparator<? super E> comparator) {
@@ -85,73 +114,53 @@
/**
* Creates a <tt>PriorityBlockingQueue</tt> containing the elements
- * in the specified collection. The priority queue has an initial
- * capacity of 110% of the size of the specified collection. If
- * the specified collection is a {@link SortedSet} or a {@link
- * PriorityQueue}, this priority queue will be sorted according to
- * the same comparator, or according to its elements' natural
- * order if the collection is sorted according to its elements'
- * natural order. Otherwise, this priority queue is ordered
- * according to its elements' natural order.
+ * in the specified collection. If the specified collection is a
+ * {@link SortedSet} or a {@link PriorityQueue}, this
+ * priority queue will be ordered according to the same ordering.
+ * Otherwise, this priority queue will be ordered according to the
+ * {@linkplain Comparable natural ordering} of its elements.
*
- * @param c the collection whose elements are to be placed
- * into this priority queue.
+ * @param c the collection whose elements are to be placed
+ * into this priority queue
* @throws ClassCastException if elements of the specified collection
* cannot be compared to one another according to the priority
- * queue's ordering.
- * @throws NullPointerException if <tt>c</tt> or any element within it
- * is <tt>null</tt>
+ * queue's ordering
+ * @throws NullPointerException if the specified collection or any
+ * of its elements are null
*/
public PriorityBlockingQueue(Collection<? extends E> c) {
q = new PriorityQueue<E>(c);
}
-
- // these first few override just to update doc comments
-
/**
- * Adds the specified element to this queue.
- * @param o the element to add
- * @return <tt>true</tt> (as per the general contract of
- * <tt>Collection.add</tt>).
+ * Inserts the specified element into this priority queue.
*
- * @throws NullPointerException if the specified element is <tt>null</tt>.
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Collection#add})
* @throws ClassCastException if the specified element cannot be compared
- * with elements currently in the priority queue according
- * to the priority queue's ordering.
+ * with elements currently in the priority queue according to the
+ * priority queue's ordering
+ * @throws NullPointerException if the specified element is null
*/
- public boolean add(E o) {
- return super.add(o);
- }
-
- /**
- * Returns the comparator used to order this collection, or <tt>null</tt>
- * if this collection is sorted according to its elements natural ordering
- * (using <tt>Comparable</tt>).
- *
- * @return the comparator used to order this collection, or <tt>null</tt>
- * if this collection is sorted according to its elements natural ordering.
- */
- public Comparator comparator() {
- return q.comparator();
+ public boolean add(E e) {
+ return offer(e);
}
/**
* Inserts the specified element into this priority queue.
*
- * @param o the element to add
- * @return <tt>true</tt>
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Queue#offer})
* @throws ClassCastException if the specified element cannot be compared
- * with elements currently in the priority queue according
- * to the priority queue's ordering.
- * @throws NullPointerException if the specified element is <tt>null</tt>.
+ * with elements currently in the priority queue according to the
+ * priority queue's ordering
+ * @throws NullPointerException if the specified element is null
*/
- public boolean offer(E o) {
- if (o == null) throw new NullPointerException();
+ public boolean offer(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
- boolean ok = q.offer(o);
+ boolean ok = q.offer(e);
assert ok;
notEmpty.signal();
return true;
@@ -161,32 +170,44 @@
}
/**
- * Adds the specified element to this priority queue. As the queue is
+ * Inserts the specified element into this priority queue. As the queue is
* unbounded this method will never block.
- * @param o the element to add
- * @throws ClassCastException if the element cannot be compared
- * with elements currently in the priority queue according
- * to the priority queue's ordering.
- * @throws NullPointerException if the specified element is <tt>null</tt>.
+ *
+ * @param e the element to add
+ * @throws ClassCastException if the specified element cannot be compared
+ * with elements currently in the priority queue according to the
+ * priority queue's ordering
+ * @throws NullPointerException if the specified element is null
*/
- public void put(E o) {
- offer(o); // never need to block
+ public void put(E e) {
+ offer(e); // never need to block
}
/**
* Inserts the specified element into this priority queue. As the queue is
* unbounded this method will never block.
- * @param o the element to add
+ *
+ * @param e the element to add
* @param timeout This parameter is ignored as the method never blocks
* @param unit This parameter is ignored as the method never blocks
* @return <tt>true</tt>
- * @throws ClassCastException if the element cannot be compared
- * with elements currently in the priority queue according
- * to the priority queue's ordering.
- * @throws NullPointerException if the specified element is <tt>null</tt>.
+ * @throws ClassCastException if the specified element cannot be compared
+ * with elements currently in the priority queue according to the
+ * priority queue's ordering
+ * @throws NullPointerException if the specified element is null
*/
- public boolean offer(E o, long timeout, TimeUnit unit) {
- return offer(o); // never need to block
+ public boolean offer(E e, long timeout, TimeUnit unit) {
+ return offer(e); // never need to block
+ }
+
+ public E poll() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.poll();
+ } finally {
+ lock.unlock();
+ }
}
public E take() throws InterruptedException {
@@ -208,17 +229,6 @@
}
}
-
- public E poll() {
- final ReentrantLock lock = this.lock;
- lock.lock();
- try {
- return q.poll();
- } finally {
- lock.unlock();
- }
- }
-
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
@@ -252,6 +262,19 @@
}
}
+ /**
+ * Returns the comparator used to order the elements in this queue,
+ * or <tt>null</tt> if this queue uses the {@linkplain Comparable
+ * natural ordering} of its elements.
+ *
+ * @return the comparator used to order the elements in this queue,
+ * or <tt>null</tt> if this queue uses the natural
+ * ordering of its elements
+ */
+ public Comparator<? super E> comparator() {
+ return q.comparator();
+ }
+
public int size() {
final ReentrantLock lock = this.lock;
lock.lock();
@@ -271,6 +294,17 @@
return Integer.MAX_VALUE;
}
+ /**
+ * Removes a single instance of the specified element from this queue,
+ * if it is present. More formally, removes an element {@code e} such
+ * that {@code o.equals(e)}, if this queue contains one or more such
+ * elements. Returns {@code true} if and only if this queue contained
+ * the specified element (or equivalently, if this queue changed as a
+ * result of the call).
+ *
+ * @param o element to be removed from this queue, if present
+ * @return <tt>true</tt> if this queue changed as a result of the call
+ */
public boolean remove(Object o) {
final ReentrantLock lock = this.lock;
lock.lock();
@@ -281,6 +315,14 @@
}
}
+ /**
+ * Returns {@code true} if this queue contains the specified element.
+ * More formally, returns {@code true} if and only if this queue contains
+ * at least one element {@code e} such that {@code o.equals(e)}.
+ *
+ * @param o object to be checked for containment in this queue
+ * @return <tt>true</tt> if this queue contains the specified element
+ */
public boolean contains(Object o) {
final ReentrantLock lock = this.lock;
lock.lock();
@@ -291,6 +333,19 @@
}
}
+ /**
+ * Returns an array containing all of the elements in this queue.
+ * The returned array elements are in no particular order.
+ *
+ * <p>The returned array will be "safe" in that no references to it are
+ * maintained by this queue. (In other words, this method must allocate
+ * a new array). The caller is thus free to modify the returned array.
+ *
+ * <p>This method acts as bridge between array-based and collection-based
+ * APIs.
+ *
+ * @return an array containing all of the elements in this queue
+ */
public Object[] toArray() {
final ReentrantLock lock = this.lock;
lock.lock();
@@ -312,6 +367,12 @@
}
}
+ /**
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
public int drainTo(Collection<? super E> c) {
if (c == null)
throw new NullPointerException();
@@ -332,6 +393,12 @@
}
}
+ /**
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
public int drainTo(Collection<? super E> c, int maxElements) {
if (c == null)
throw new NullPointerException();
@@ -355,7 +422,7 @@
}
/**
- * Atomically removes all of the elements from this delay queue.
+ * Atomically removes all of the elements from this queue.
* The queue will be empty after this call returns.
*/
public void clear() {
@@ -368,6 +435,43 @@
}
}
+ /**
+ * Returns an array containing all of the elements in this queue; the
+ * runtime type of the returned array is that of the specified array.
+ * The returned array elements are in no particular order.
+ * If the queue fits in the specified array, it is returned therein.
+ * Otherwise, a new array is allocated with the runtime type of the
+ * specified array and the size of this queue.
+ *
+ * <p>If this queue fits in the specified array with room to spare
+ * (i.e., the array has more elements than this queue), the element in
+ * the array immediately following the end of the queue is set to
+ * <tt>null</tt>.
+ *
+ * <p>Like the {@link #toArray()} method, this method acts as bridge between
+ * array-based and collection-based APIs. Further, this method allows
+ * precise control over the runtime type of the output array, and may,
+ * under certain circumstances, be used to save allocation costs.
+ *
+ * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
+ * The following code can be used to dump the queue into a newly
+ * allocated array of <tt>String</tt>:
+ *
+ * <pre>
+ * String[] y = x.toArray(new String[0]);</pre>
+ *
+ * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+ * <tt>toArray()</tt>.
+ *
+ * @param a the array into which the elements of the queue are to
+ * be stored, if it is big enough; otherwise, a new array of the
+ * same runtime type is allocated for this purpose
+ * @return an array containing all of the elements in this queue
+ * @throws ArrayStoreException if the runtime type of the specified array
+ * is not a supertype of the runtime type of every element in
+ * this queue
+ * @throws NullPointerException if the specified array is null
+ */
public <T> T[] toArray(T[] a) {
final ReentrantLock lock = this.lock;
lock.lock();
@@ -381,54 +485,58 @@
/**
* Returns an iterator over the elements in this queue. The
* iterator does not return the elements in any particular order.
- * The returned iterator is a thread-safe "fast-fail" iterator
- * that will throw {@link
- * java.util.ConcurrentModificationException} upon detected
- * interference.
+ * The returned <tt>Iterator</tt> is a "weakly consistent"
+ * iterator that will never throw {@link
+ * ConcurrentModificationException}, and guarantees to traverse
+ * elements as they existed upon construction of the iterator, and
+ * may (but is not guaranteed to) reflect any modifications
+ * subsequent to construction.
*
- * @return an iterator over the elements in this queue.
+ * @return an iterator over the elements in this queue
*/
public Iterator<E> iterator() {
- final ReentrantLock lock = this.lock;
- lock.lock();
- try {
- return new Itr(q.iterator());
- } finally {
- lock.unlock();
- }
+ return new Itr(toArray());
}
- private class Itr<E> implements Iterator<E> {
- private final Iterator<E> iter;
- Itr(Iterator<E> i) {
- iter = i;
+ /**
+ * Snapshot iterator that works off copy of underlying q array.
+ */
+ private class Itr implements Iterator<E> {
+ final Object[] array; // Array of all elements
+ int cursor; // index of next element to return;
+ int lastRet; // index of last element, or -1 if no such
+
+ Itr(Object[] array) {
+ lastRet = -1;
+ this.array = array;
}
public boolean hasNext() {
- /*
- * No sync -- we rely on underlying hasNext to be
- * stateless, in which case we can return true by mistake
- * only when next() will subsequently throw
- * ConcurrentModificationException.
- */
- return iter.hasNext();
+ return cursor < array.length;
}
public E next() {
- ReentrantLock lock = PriorityBlockingQueue.this.lock;
- lock.lock();
- try {
- return iter.next();
- } finally {
- lock.unlock();
- }
+ if (cursor >= array.length)
+ throw new NoSuchElementException();
+ lastRet = cursor;
+ return (E)array[cursor++];
}
public void remove() {
- ReentrantLock lock = PriorityBlockingQueue.this.lock;
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ Object x = array[lastRet];
+ lastRet = -1;
+ // Traverse underlying queue to find == element,
+ // not just a .equals element.
lock.lock();
try {
- iter.remove();
+ for (Iterator it = q.iterator(); it.hasNext(); ) {
+ if (it.next() == x) {
+ it.remove();
+ return;
+ }
+ }
} finally {
lock.unlock();
}
@@ -436,7 +544,7 @@
}
/**
- * Save the state to a stream (that is, serialize it). This
+ * Saves the state to a stream (that is, serializes it). This
* merely wraps default serialization within lock. The
* serialization strategy for items is left to underlying
* Queue. Note that locking is not needed on deserialization, so
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java Tue Jul 28 09:30:33 2009
@@ -9,7 +9,7 @@
/**
* Exception thrown by an {@link Executor} when a task cannot be
* accepted for execution.
- *
+ *
* @since 1.5
* @author Doug Lea
*/
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java Tue Jul 28 09:30:33 2009
@@ -7,8 +7,7 @@
package java.util.concurrent;
/**
- * A handler for tasks that cannot be executed by a {@link
- * ThreadPoolExecutor}.
+ * A handler for tasks that cannot be executed by a {@link ThreadPoolExecutor}.
*
* @since 1.5
* @author Doug Lea
@@ -17,13 +16,14 @@
/**
* Method that may be invoked by a {@link ThreadPoolExecutor} when
- * <tt>execute</tt> cannot accept a task. This may occur when no
- * more threads or queue slots are available because their bounds
- * would be exceeded, or upon shutdown of the Executor.
+ * {@link ThreadPoolExecutor#execute execute} cannot accept a
+ * task. This may occur when no more threads or queue slots are
+ * available because their bounds would be exceeded, or upon
+ * shutdown of the Executor.
*
- * In the absence other alternatives, the method may throw an
- * unchecked {@link RejectedExecutionException}, which will be
- * propagated to the caller of <tt>execute</tt>.
+ * <p>In the absence of other alternatives, the method may throw
+ * an unchecked {@link RejectedExecutionException}, which will be
+ * propagated to the caller of {@code execute}.
*
* @param r the runnable task requested to be executed
* @param executor the executor attempting to execute this task