提交 4a06ae96 编写于 作者: D dl

8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012

Reviewed-by: chegar, dholmes
上级 30881c22
...@@ -158,7 +158,7 @@ public abstract class AbstractExecutorService implements ExecutorService { ...@@ -158,7 +158,7 @@ public abstract class AbstractExecutorService implements ExecutorService {
// Record exceptions so that if we fail to obtain any // Record exceptions so that if we fail to obtain any
// result, we can throw the last exception we got. // result, we can throw the last exception we got.
ExecutionException ee = null; ExecutionException ee = null;
long lastTime = timed ? System.nanoTime() : 0; final long deadline = timed ? System.nanoTime() + nanos : 0L;
Iterator<? extends Callable<T>> it = tasks.iterator(); Iterator<? extends Callable<T>> it = tasks.iterator();
// Start one task for sure; the rest incrementally // Start one task for sure; the rest incrementally
...@@ -180,9 +180,7 @@ public abstract class AbstractExecutorService implements ExecutorService { ...@@ -180,9 +180,7 @@ public abstract class AbstractExecutorService implements ExecutorService {
f = ecs.poll(nanos, TimeUnit.NANOSECONDS); f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
if (f == null) if (f == null)
throw new TimeoutException(); throw new TimeoutException();
long now = System.nanoTime(); nanos = deadline - System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
} }
else else
f = ecs.take(); f = ecs.take();
...@@ -258,7 +256,7 @@ public abstract class AbstractExecutorService implements ExecutorService { ...@@ -258,7 +256,7 @@ public abstract class AbstractExecutorService implements ExecutorService {
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit) long timeout, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
if (tasks == null || unit == null) if (tasks == null)
throw new NullPointerException(); throw new NullPointerException();
long nanos = unit.toNanos(timeout); long nanos = unit.toNanos(timeout);
List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
...@@ -267,23 +265,21 @@ public abstract class AbstractExecutorService implements ExecutorService { ...@@ -267,23 +265,21 @@ public abstract class AbstractExecutorService implements ExecutorService {
for (Callable<T> t : tasks) for (Callable<T> t : tasks)
futures.add(newTaskFor(t)); futures.add(newTaskFor(t));
long lastTime = System.nanoTime(); final long deadline = System.nanoTime() + nanos;
// Interleave time checks and calls to execute in case // Interleave time checks and calls to execute in case
// executor doesn't have any/much parallelism. // executor doesn't have any/much parallelism.
Iterator<Future<T>> it = futures.iterator(); Iterator<Future<T>> it = futures.iterator();
while (it.hasNext()) { while (it.hasNext()) {
execute((Runnable)(it.next())); execute((Runnable)(it.next()));
long now = System.nanoTime(); nanos = deadline - System.nanoTime();
nanos -= now - lastTime; if (nanos <= 0L)
lastTime = now;
if (nanos <= 0)
return futures; return futures;
} }
for (Future<T> f : futures) { for (Future<T> f : futures) {
if (!f.isDone()) { if (!f.isDone()) {
if (nanos <= 0) if (nanos <= 0L)
return futures; return futures;
try { try {
f.get(nanos, TimeUnit.NANOSECONDS); f.get(nanos, TimeUnit.NANOSECONDS);
...@@ -292,9 +288,7 @@ public abstract class AbstractExecutorService implements ExecutorService { ...@@ -292,9 +288,7 @@ public abstract class AbstractExecutorService implements ExecutorService {
} catch (TimeoutException toe) { } catch (TimeoutException toe) {
return futures; return futures;
} }
long now = System.nanoTime(); nanos = deadline - System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
} }
} }
done = true; done = true;
......
...@@ -127,7 +127,7 @@ import java.util.Queue; ...@@ -127,7 +127,7 @@ import java.util.Queue;
* Usage example, based on a typical producer-consumer scenario. * Usage example, based on a typical producer-consumer scenario.
* Note that a <tt>BlockingQueue</tt> can safely be used with multiple * Note that a <tt>BlockingQueue</tt> can safely be used with multiple
* producers and multiple consumers. * producers and multiple consumers.
* <pre> * <pre> {@code
* class Producer implements Runnable { * class Producer implements Runnable {
* private final BlockingQueue queue; * private final BlockingQueue queue;
* Producer(BlockingQueue q) { queue = q; } * Producer(BlockingQueue q) { queue = q; }
...@@ -160,8 +160,7 @@ import java.util.Queue; ...@@ -160,8 +160,7 @@ import java.util.Queue;
* new Thread(c1).start(); * new Thread(c1).start();
* new Thread(c2).start(); * new Thread(c2).start();
* } * }
* } * }}</pre>
* </pre>
* *
* <p>Memory consistency effects: As with other concurrent * <p>Memory consistency effects: As with other concurrent
* collections, actions in a thread prior to placing an object into a * collections, actions in a thread prior to placing an object into a
......
...@@ -44,7 +44,6 @@ package java.util.concurrent; ...@@ -44,7 +44,6 @@ package java.util.concurrent;
* *
* @since 1.5 * @since 1.5
* @author Doug Lea * @author Doug Lea
*
*/ */
public class BrokenBarrierException extends Exception { public class BrokenBarrierException extends Exception {
private static final long serialVersionUID = 7117394618823254244L; private static final long serialVersionUID = 7117394618823254244L;
......
...@@ -57,7 +57,6 @@ package java.util.concurrent; ...@@ -57,7 +57,6 @@ package java.util.concurrent;
* <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
* actions taken by that task, which in turn <i>happen-before</i> * actions taken by that task, which in turn <i>happen-before</i>
* actions following a successful return from the corresponding {@code take()}. * actions following a successful return from the corresponding {@code take()}.
*
*/ */
public interface CompletionService<V> { public interface CompletionService<V> {
/** /**
...@@ -98,7 +97,6 @@ public interface CompletionService<V> { ...@@ -98,7 +97,6 @@ public interface CompletionService<V> {
*/ */
Future<V> take() throws InterruptedException; Future<V> take() throws InterruptedException;
/** /**
* Retrieves and removes the Future representing the next * Retrieves and removes the Future representing the next
* completed task or <tt>null</tt> if none are present. * completed task or <tt>null</tt> if none are present.
......
...@@ -90,7 +90,6 @@ import java.util.Queue; ...@@ -90,7 +90,6 @@ import java.util.Queue;
* @author Martin Buchholz * @author Martin Buchholz
* @param <E> the type of elements held in this collection * @param <E> the type of elements held in this collection
*/ */
public class ConcurrentLinkedDeque<E> public class ConcurrentLinkedDeque<E>
extends AbstractCollection<E> extends AbstractCollection<E>
implements Deque<E>, java.io.Serializable { implements Deque<E>, java.io.Serializable {
...@@ -1250,8 +1249,7 @@ public class ConcurrentLinkedDeque<E> ...@@ -1250,8 +1249,7 @@ public class ConcurrentLinkedDeque<E>
* The following code can be used to dump the deque into a newly * The following code can be used to dump the deque into a newly
* allocated array of {@code String}: * allocated array of {@code String}:
* *
* <pre> * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
* String[] y = x.toArray(new String[0]);</pre>
* *
* Note that {@code toArray(new Object[0])} is identical in function to * Note that {@code toArray(new Object[0])} is identical in function to
* {@code toArray()}. * {@code toArray()}.
...@@ -1388,11 +1386,10 @@ public class ConcurrentLinkedDeque<E> ...@@ -1388,11 +1386,10 @@ public class ConcurrentLinkedDeque<E>
} }
/** /**
* Saves the state to a stream (that is, serializes it). * Saves this deque to a stream (that is, serializes it).
* *
* @serialData All of the elements (each an {@code E}) in * @serialData All of the elements (each an {@code E}) in
* the proper order, followed by a null * the proper order, followed by a null
* @param s the stream
*/ */
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException { throws java.io.IOException {
...@@ -1412,8 +1409,7 @@ public class ConcurrentLinkedDeque<E> ...@@ -1412,8 +1409,7 @@ public class ConcurrentLinkedDeque<E>
} }
/** /**
* Reconstitutes the instance from a stream (that is, deserializes it). * Reconstitutes this deque from a stream (that is, deserializes it).
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
...@@ -1436,7 +1432,6 @@ public class ConcurrentLinkedDeque<E> ...@@ -1436,7 +1432,6 @@ public class ConcurrentLinkedDeque<E>
initHeadTail(h, t); initHeadTail(h, t);
} }
private boolean casHead(Node<E> cmp, Node<E> val) { private boolean casHead(Node<E> cmp, Node<E> val) {
return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
} }
......
...@@ -98,7 +98,6 @@ import java.util.Queue; ...@@ -98,7 +98,6 @@ import java.util.Queue;
* @since 1.5 * @since 1.5
* @author Doug Lea * @author Doug Lea
* @param <E> the type of elements held in this collection * @param <E> the type of elements held in this collection
*
*/ */
public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
implements Queue<E>, java.io.Serializable { implements Queue<E>, java.io.Serializable {
...@@ -247,7 +246,6 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> ...@@ -247,7 +246,6 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
*/ */
private transient volatile Node<E> tail; private transient volatile Node<E> tail;
/** /**
* Creates a {@code ConcurrentLinkedQueue} that is initially empty. * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
*/ */
...@@ -609,8 +607,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> ...@@ -609,8 +607,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
* The following code can be used to dump the queue into a newly * The following code can be used to dump the queue into a newly
* allocated array of {@code String}: * allocated array of {@code String}:
* *
* <pre> * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
* String[] y = x.toArray(new String[0]);</pre>
* *
* Note that {@code toArray(new Object[0])} is identical in function to * Note that {@code toArray(new Object[0])} is identical in function to
* {@code toArray()}. * {@code toArray()}.
...@@ -747,11 +744,10 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> ...@@ -747,11 +744,10 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
} }
/** /**
* Saves the state to a stream (that is, serializes it). * Saves this queue to a stream (that is, serializes it).
* *
* @serialData All of the elements (each an {@code E}) in * @serialData All of the elements (each an {@code E}) in
* the proper order, followed by a null * the proper order, followed by a null
* @param s the stream
*/ */
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException { throws java.io.IOException {
...@@ -771,8 +767,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> ...@@ -771,8 +767,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
} }
/** /**
* Reconstitutes the instance from a stream (that is, deserializes it). * Reconstitutes this queue from a stream (that is, deserializes it).
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
......
...@@ -61,11 +61,12 @@ public interface ConcurrentMap<K, V> extends Map<K, V> { ...@@ -61,11 +61,12 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* If the specified key is not already associated * If the specified key is not already associated
* with a value, associate it with the given value. * with a value, associate it with the given value.
* This is equivalent to * This is equivalent to
* <pre> * <pre> {@code
* if (!map.containsKey(key)) * if (!map.containsKey(key))
* return map.put(key, value); * return map.put(key, value);
* else * else
* return map.get(key);</pre> * return map.get(key);}</pre>
*
* except that the action is performed atomically. * except that the action is performed atomically.
* *
* @param key key with which the specified value is to be associated * @param key key with which the specified value is to be associated
...@@ -83,18 +84,19 @@ public interface ConcurrentMap<K, V> extends Map<K, V> { ...@@ -83,18 +84,19 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* and this map does not permit null keys or values * and this map does not permit null keys or values
* @throws IllegalArgumentException if some property of the specified key * @throws IllegalArgumentException if some property of the specified key
* or value prevents it from being stored in this map * or value prevents it from being stored in this map
*
*/ */
V putIfAbsent(K key, V value); V putIfAbsent(K key, V value);
/** /**
* Removes the entry for a key only if currently mapped to a given value. * Removes the entry for a key only if currently mapped to a given value.
* This is equivalent to * This is equivalent to
* <pre> * <pre> {@code
* if (map.containsKey(key) &amp;&amp; map.get(key).equals(value)) { * if (map.containsKey(key) && map.get(key).equals(value)) {
* map.remove(key); * map.remove(key);
* return true; * return true;
* } else return false;</pre> * } else
* return false;}</pre>
*
* except that the action is performed atomically. * except that the action is performed atomically.
* *
* @param key key with which the specified value is associated * @param key key with which the specified value is associated
...@@ -114,11 +116,13 @@ public interface ConcurrentMap<K, V> extends Map<K, V> { ...@@ -114,11 +116,13 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
/** /**
* Replaces the entry for a key only if currently mapped to a given value. * Replaces the entry for a key only if currently mapped to a given value.
* This is equivalent to * This is equivalent to
* <pre> * <pre> {@code
* if (map.containsKey(key) &amp;&amp; map.get(key).equals(oldValue)) { * if (map.containsKey(key) && map.get(key).equals(oldValue)) {
* map.put(key, newValue); * map.put(key, newValue);
* return true; * return true;
* } else return false;</pre> * } else
* return false;}</pre>
*
* except that the action is performed atomically. * except that the action is performed atomically.
* *
* @param key key with which the specified value is associated * @param key key with which the specified value is associated
...@@ -139,10 +143,12 @@ public interface ConcurrentMap<K, V> extends Map<K, V> { ...@@ -139,10 +143,12 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
/** /**
* Replaces the entry for a key only if currently mapped to some value. * Replaces the entry for a key only if currently mapped to some value.
* This is equivalent to * This is equivalent to
* <pre> * <pre> {@code
* if (map.containsKey(key)) { * if (map.containsKey(key)) {
* return map.put(key, value); * return map.put(key, value);
* } else return null;</pre> * } else
* return null;}</pre>
*
* except that the action is performed atomically. * except that the action is performed atomically.
* *
* @param key key with which the specified value is associated * @param key key with which the specified value is associated
......
...@@ -67,7 +67,6 @@ public interface ConcurrentNavigableMap<K,V> ...@@ -67,7 +67,6 @@ public interface ConcurrentNavigableMap<K,V>
*/ */
ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive); ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive);
/** /**
* @throws ClassCastException {@inheritDoc} * @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
......
...@@ -1507,7 +1507,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> ...@@ -1507,7 +1507,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
/* ---------------- Serialization -------------- */ /* ---------------- Serialization -------------- */
/** /**
* Saves the state of this map to a stream (that is, serializes it). * Saves this map to a stream (that is, serializes it).
* *
* @serialData The key (Object) and value (Object) for each * @serialData The key (Object) and value (Object) for each
* key-value mapping represented by the map, followed by * key-value mapping represented by the map, followed by
...@@ -1532,9 +1532,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> ...@@ -1532,9 +1532,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
} }
/** /**
* Reconstitutes the map from a stream (that is, deserializes it). * Reconstitutes this map from a stream (that is, deserializes it).
*
* @param s the stream
*/ */
private void readObject(final java.io.ObjectInputStream s) private void readObject(final java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
package java.util.concurrent; package java.util.concurrent;
import java.util.*; import java.util.*;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.ReentrantLock;
/** /**
* A thread-safe variant of {@link java.util.ArrayList} in which all mutative * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
...@@ -152,7 +152,7 @@ public class CopyOnWriteArrayList<E> ...@@ -152,7 +152,7 @@ public class CopyOnWriteArrayList<E>
} }
/** /**
* Test for equality, coping with nulls. * Tests for equality, coping with nulls.
*/ */
private static boolean eq(Object o1, Object o2) { private static boolean eq(Object o1, Object o2) {
return (o1 == null ? o2 == null : o1.equals(o2)); return (o1 == null ? o2 == null : o1.equals(o2));
...@@ -333,8 +333,7 @@ public class CopyOnWriteArrayList<E> ...@@ -333,8 +333,7 @@ public class CopyOnWriteArrayList<E>
* The following code can be used to dump the list into a newly * The following code can be used to dump the list into a newly
* allocated array of <tt>String</tt>: * allocated array of <tt>String</tt>:
* *
* <pre> * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
* String[] y = x.toArray(new String[0]);</pre>
* *
* Note that <tt>toArray(new Object[0])</tt> is identical in function to * Note that <tt>toArray(new Object[0])</tt> is identical in function to
* <tt>toArray()</tt>. * <tt>toArray()</tt>.
...@@ -548,9 +547,9 @@ public class CopyOnWriteArrayList<E> ...@@ -548,9 +547,9 @@ public class CopyOnWriteArrayList<E>
* @param fromIndex index of first element to be removed * @param fromIndex index of first element to be removed
* @param toIndex index after last element to be removed * @param toIndex index after last element to be removed
* @throws IndexOutOfBoundsException if fromIndex or toIndex out of range * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
* ({@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex}) * ({@code fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
*/ */
private void removeRange(int fromIndex, int toIndex) { void removeRange(int fromIndex, int toIndex) {
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
...@@ -576,7 +575,7 @@ public class CopyOnWriteArrayList<E> ...@@ -576,7 +575,7 @@ public class CopyOnWriteArrayList<E>
} }
/** /**
* Append the element if not present. * Appends the element, if not present.
* *
* @param e element to be added to this list, if absent * @param e element to be added to this list, if absent
* @return <tt>true</tt> if the element was added * @return <tt>true</tt> if the element was added
...@@ -641,6 +640,7 @@ public class CopyOnWriteArrayList<E> ...@@ -641,6 +640,7 @@ public class CopyOnWriteArrayList<E>
* @see #remove(Object) * @see #remove(Object)
*/ */
public boolean removeAll(Collection<?> c) { public boolean removeAll(Collection<?> c) {
if (c == null) throw new NullPointerException();
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
...@@ -683,6 +683,7 @@ public class CopyOnWriteArrayList<E> ...@@ -683,6 +683,7 @@ public class CopyOnWriteArrayList<E>
* @see #remove(Object) * @see #remove(Object)
*/ */
public boolean retainAll(Collection<?> c) { public boolean retainAll(Collection<?> c) {
if (c == null) throw new NullPointerException();
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
...@@ -837,15 +838,14 @@ public class CopyOnWriteArrayList<E> ...@@ -837,15 +838,14 @@ public class CopyOnWriteArrayList<E>
} }
/** /**
* Saves the state of the list to a stream (that is, serializes it). * Saves this list to a stream (that is, serializes it).
* *
* @serialData The length of the array backing the list is emitted * @serialData The length of the array backing the list is emitted
* (int), followed by all of its elements (each an Object) * (int), followed by all of its elements (each an Object)
* in the proper order. * in the proper order.
* @param s the stream
*/ */
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{ throws java.io.IOException {
s.defaultWriteObject(); s.defaultWriteObject();
...@@ -859,9 +859,7 @@ public class CopyOnWriteArrayList<E> ...@@ -859,9 +859,7 @@ public class CopyOnWriteArrayList<E>
} }
/** /**
* Reconstitutes the list from a stream (that is, deserializes it). * Reconstitutes this list from a stream (that is, deserializes it).
*
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
...@@ -1266,17 +1264,14 @@ public class CopyOnWriteArrayList<E> ...@@ -1266,17 +1264,14 @@ public class CopyOnWriteArrayList<E>
private static class COWSubListIterator<E> implements ListIterator<E> { private static class COWSubListIterator<E> implements ListIterator<E> {
private final ListIterator<E> i; private final ListIterator<E> it;
private final int index;
private final int offset; private final int offset;
private final int size; private final int size;
COWSubListIterator(List<E> l, int index, int offset, COWSubListIterator(List<E> l, int index, int offset, int size) {
int size) {
this.index = index;
this.offset = offset; this.offset = offset;
this.size = size; this.size = size;
i = l.listIterator(index+offset); it = l.listIterator(index+offset);
} }
public boolean hasNext() { public boolean hasNext() {
...@@ -1285,7 +1280,7 @@ public class CopyOnWriteArrayList<E> ...@@ -1285,7 +1280,7 @@ public class CopyOnWriteArrayList<E>
public E next() { public E next() {
if (hasNext()) if (hasNext())
return i.next(); return it.next();
else else
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
...@@ -1296,17 +1291,17 @@ public class CopyOnWriteArrayList<E> ...@@ -1296,17 +1291,17 @@ public class CopyOnWriteArrayList<E>
public E previous() { public E previous() {
if (hasPrevious()) if (hasPrevious())
return i.previous(); return it.previous();
else else
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
public int nextIndex() { public int nextIndex() {
return i.nextIndex() - offset; return it.nextIndex() - offset;
} }
public int previousIndex() { public int previousIndex() {
return i.previousIndex() - offset; return it.previousIndex() - offset;
} }
public void remove() { public void remove() {
......
...@@ -189,8 +189,7 @@ public class CopyOnWriteArraySet<E> extends AbstractSet<E> ...@@ -189,8 +189,7 @@ public class CopyOnWriteArraySet<E> extends AbstractSet<E>
* The following code can be used to dump the set into a newly allocated * The following code can be used to dump the set into a newly allocated
* array of <tt>String</tt>: * array of <tt>String</tt>:
* *
* <pre> * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
* String[] y = x.toArray(new String[0]);</pre>
* *
* Note that <tt>toArray(new Object[0])</tt> is identical in function to * Note that <tt>toArray(new Object[0])</tt> is identical in function to
* <tt>toArray()</tt>. * <tt>toArray()</tt>.
...@@ -384,9 +383,9 @@ public class CopyOnWriteArraySet<E> extends AbstractSet<E> ...@@ -384,9 +383,9 @@ public class CopyOnWriteArraySet<E> extends AbstractSet<E>
} }
/** /**
* Test for equality, coping with nulls. * Tests for equality, coping with nulls.
*/ */
private static boolean eq(Object o1, Object o2) { private static boolean eq(Object o1, Object o2) {
return (o1 == null ? o2 == null : o1.equals(o2)); return (o1 == null) ? o2 == null : o1.equals(o2);
} }
} }
...@@ -34,8 +34,7 @@ ...@@ -34,8 +34,7 @@
*/ */
package java.util.concurrent; package java.util.concurrent;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.atomic.*;
/** /**
* A synchronization aid that allows one or more threads to wait until * A synchronization aid that allows one or more threads to wait until
...@@ -73,7 +72,7 @@ import java.util.concurrent.atomic.*; ...@@ -73,7 +72,7 @@ import java.util.concurrent.atomic.*;
* until all workers have completed. * until all workers have completed.
* </ul> * </ul>
* *
* <pre> * <pre> {@code
* class Driver { // ... * class Driver { // ...
* void main() throws InterruptedException { * void main() throws InterruptedException {
* CountDownLatch startSignal = new CountDownLatch(1); * CountDownLatch startSignal = new CountDownLatch(1);
...@@ -105,9 +104,7 @@ import java.util.concurrent.atomic.*; ...@@ -105,9 +104,7 @@ import java.util.concurrent.atomic.*;
* } * }
* *
* void doWork() { ... } * void doWork() { ... }
* } * }}</pre>
*
* </pre>
* *
* <p>Another typical usage would be to divide a problem into N parts, * <p>Another typical usage would be to divide a problem into N parts,
* describe each part with a Runnable that executes that portion and * describe each part with a Runnable that executes that portion and
...@@ -116,7 +113,7 @@ import java.util.concurrent.atomic.*; ...@@ -116,7 +113,7 @@ import java.util.concurrent.atomic.*;
* will be able to pass through await. (When threads must repeatedly * will be able to pass through await. (When threads must repeatedly
* count down in this way, instead use a {@link CyclicBarrier}.) * count down in this way, instead use a {@link CyclicBarrier}.)
* *
* <pre> * <pre> {@code
* class Driver2 { // ... * class Driver2 { // ...
* void main() throws InterruptedException { * void main() throws InterruptedException {
* CountDownLatch doneSignal = new CountDownLatch(N); * CountDownLatch doneSignal = new CountDownLatch(N);
...@@ -144,9 +141,7 @@ import java.util.concurrent.atomic.*; ...@@ -144,9 +141,7 @@ import java.util.concurrent.atomic.*;
* } * }
* *
* void doWork() { ... } * void doWork() { ... }
* } * }}</pre>
*
* </pre>
* *
* <p>Memory consistency effects: Until the count reaches * <p>Memory consistency effects: Until the count reaches
* zero, actions in a thread prior to calling * zero, actions in a thread prior to calling
......
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
*/ */
package java.util.concurrent; package java.util.concurrent;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/** /**
* A synchronization aid that allows a set of threads to all wait for * A synchronization aid that allows a set of threads to all wait for
...@@ -52,7 +53,8 @@ import java.util.concurrent.locks.*; ...@@ -52,7 +53,8 @@ import java.util.concurrent.locks.*;
* *
* <p><b>Sample usage:</b> Here is an example of * <p><b>Sample usage:</b> Here is an example of
* using a barrier in a parallel decomposition design: * using a barrier in a parallel decomposition design:
* <pre> *
* <pre> {@code
* class Solver { * class Solver {
* final int N; * final int N;
* final float[][] data; * final float[][] data;
...@@ -90,8 +92,8 @@ import java.util.concurrent.locks.*; ...@@ -90,8 +92,8 @@ import java.util.concurrent.locks.*;
* *
* waitUntilDone(); * waitUntilDone();
* } * }
* } * }}</pre>
* </pre> *
* Here, each worker thread processes a row of the matrix then waits at the * Here, each worker thread processes a row of the matrix then waits at the
* barrier until all rows have been processed. When all rows are processed * barrier until all rows have been processed. When all rows are processed
* the supplied {@link Runnable} barrier action is executed and merges the * the supplied {@link Runnable} barrier action is executed and merges the
...@@ -105,9 +107,10 @@ import java.util.concurrent.locks.*; ...@@ -105,9 +107,10 @@ import java.util.concurrent.locks.*;
* {@link #await} returns the arrival index of that thread at the barrier. * {@link #await} returns the arrival index of that thread at the barrier.
* You can then choose which thread should execute the barrier action, for * You can then choose which thread should execute the barrier action, for
* example: * example:
* <pre> if (barrier.await() == 0) { * <pre> {@code
* if (barrier.await() == 0) {
* // log the completion of this iteration * // log the completion of this iteration
* }</pre> * }}</pre>
* *
* <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model
* for failed synchronization attempts: If a thread leaves a barrier * for failed synchronization attempts: If a thread leaves a barrier
...@@ -354,7 +357,7 @@ public class CyclicBarrier { ...@@ -354,7 +357,7 @@ public class CyclicBarrier {
try { try {
return dowait(false, 0L); return dowait(false, 0L);
} catch (TimeoutException toe) { } catch (TimeoutException toe) {
throw new Error(toe); // cannot happen; throw new Error(toe); // cannot happen
} }
} }
......
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
package java.util.concurrent; package java.util.concurrent;
import java.util.*;
/** /**
* A mix-in style interface for marking objects that should be * A mix-in style interface for marking objects that should be
* acted upon after a given delay. * acted upon after a given delay.
......
...@@ -79,11 +79,9 @@ public class ExecutionException extends Exception { ...@@ -79,11 +79,9 @@ public class ExecutionException extends Exception {
/** /**
* Constructs an <tt>ExecutionException</tt> with the specified cause. * Constructs an <tt>ExecutionException</tt> with the specified cause.
* The detail message is set to: * The detail message is set to {@code (cause == null ? null :
* <pre> * cause.toString())} (which typically contains the class and
* (cause == null ? null : cause.toString())</pre> * detail message of {@code cause}).
* (which typically contains the class and detail message of
* <tt>cause</tt>).
* *
* @param cause the cause (which is saved for later retrieval by the * @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method) * {@link #getCause()} method)
......
...@@ -56,23 +56,23 @@ package java.util.concurrent; ...@@ -56,23 +56,23 @@ package java.util.concurrent;
* executor can run the submitted task immediately in the caller's * executor can run the submitted task immediately in the caller's
* thread: * thread:
* *
* <pre> * <pre> {@code
* class DirectExecutor implements Executor { * class DirectExecutor implements Executor {
* public void execute(Runnable r) { * public void execute(Runnable r) {
* r.run(); * r.run();
* } * }
* }</pre> * }}</pre>
* *
* More typically, tasks are executed in some thread other * More typically, tasks are executed in some thread other
* than the caller's thread. The executor below spawns a new thread * than the caller's thread. The executor below spawns a new thread
* for each task. * for each task.
* *
* <pre> * <pre> {@code
* class ThreadPerTaskExecutor implements Executor { * class ThreadPerTaskExecutor implements Executor {
* public void execute(Runnable r) { * public void execute(Runnable r) {
* new Thread(r).start(); * new Thread(r).start();
* } * }
* }</pre> * }}</pre>
* *
* Many <tt>Executor</tt> implementations impose some sort of * Many <tt>Executor</tt> implementations impose some sort of
* limitation on how and when tasks are scheduled. The executor below * limitation on how and when tasks are scheduled. The executor below
......
...@@ -36,8 +36,6 @@ ...@@ -36,8 +36,6 @@
package java.util.concurrent; package java.util.concurrent;
import java.util.List; import java.util.List;
import java.util.Collection; import java.util.Collection;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
/** /**
* An {@link Executor} that provides methods to manage termination and * An {@link Executor} that provides methods to manage termination and
...@@ -73,7 +71,7 @@ import java.security.PrivilegedExceptionAction; ...@@ -73,7 +71,7 @@ import java.security.PrivilegedExceptionAction;
* pool service incoming requests. It uses the preconfigured {@link * pool service incoming requests. It uses the preconfigured {@link
* Executors#newFixedThreadPool} factory method: * Executors#newFixedThreadPool} factory method:
* *
* <pre> * <pre> {@code
* class NetworkService implements Runnable { * class NetworkService implements Runnable {
* private final ServerSocket serverSocket; * private final ServerSocket serverSocket;
* private final ExecutorService pool; * private final ExecutorService pool;
...@@ -101,14 +99,13 @@ import java.security.PrivilegedExceptionAction; ...@@ -101,14 +99,13 @@ import java.security.PrivilegedExceptionAction;
* public void run() { * public void run() {
* // read and service request on socket * // read and service request on socket
* } * }
* } * }}</pre>
* </pre>
* *
* The following method shuts down an <tt>ExecutorService</tt> in two phases, * The following method shuts down an <tt>ExecutorService</tt> in two phases,
* first by calling <tt>shutdown</tt> to reject incoming tasks, and then * first by calling <tt>shutdown</tt> to reject incoming tasks, and then
* calling <tt>shutdownNow</tt>, if necessary, to cancel any lingering tasks: * calling <tt>shutdownNow</tt>, if necessary, to cancel any lingering tasks:
* *
* <pre> * <pre> {@code
* void shutdownAndAwaitTermination(ExecutorService pool) { * void shutdownAndAwaitTermination(ExecutorService pool) {
* pool.shutdown(); // Disable new tasks from being submitted * pool.shutdown(); // Disable new tasks from being submitted
* try { * try {
...@@ -125,8 +122,7 @@ import java.security.PrivilegedExceptionAction; ...@@ -125,8 +122,7 @@ import java.security.PrivilegedExceptionAction;
* // Preserve interrupt status * // Preserve interrupt status
* Thread.currentThread().interrupt(); * Thread.currentThread().interrupt();
* } * }
* } * }}</pre>
* </pre>
* *
* <p>Memory consistency effects: Actions in a thread prior to the * <p>Memory consistency effects: Actions in a thread prior to the
* submission of a {@code Runnable} or {@code Callable} task to an * submission of a {@code Runnable} or {@code Callable} task to an
...@@ -214,7 +210,6 @@ public interface ExecutorService extends Executor { ...@@ -214,7 +210,6 @@ public interface ExecutorService extends Executor {
boolean awaitTermination(long timeout, TimeUnit unit) boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException; throws InterruptedException;
/** /**
* Submits a value-returning task for execution and returns a * Submits a value-returning task for execution and returns a
* Future representing the pending results of the task. The * Future representing the pending results of the task. The
...@@ -286,7 +281,6 @@ public interface ExecutorService extends Executor { ...@@ -286,7 +281,6 @@ public interface ExecutorService extends Executor {
* @throws RejectedExecutionException if any task cannot be * @throws RejectedExecutionException if any task cannot be
* scheduled for execution * scheduled for execution
*/ */
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException; throws InterruptedException;
......
...@@ -922,8 +922,7 @@ public class LinkedBlockingDeque<E> ...@@ -922,8 +922,7 @@ public class LinkedBlockingDeque<E>
* The following code can be used to dump the deque into a newly * The following code can be used to dump the deque into a newly
* allocated array of {@code String}: * allocated array of {@code String}:
* *
* <pre> * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
* String[] y = x.toArray(new String[0]);</pre>
* *
* Note that {@code toArray(new Object[0])} is identical in function to * Note that {@code toArray(new Object[0])} is identical in function to
* {@code toArray()}. * {@code toArray()}.
...@@ -1153,11 +1152,10 @@ public class LinkedBlockingDeque<E> ...@@ -1153,11 +1152,10 @@ public class LinkedBlockingDeque<E>
} }
/** /**
* Save the state of this deque to a stream (that is, serialize it). * Saves this deque to a stream (that is, serializes it).
* *
* @serialData The capacity (int), followed by elements (each an * @serialData The capacity (int), followed by elements (each an
* {@code Object}) in the proper order, followed by a null * {@code Object}) in the proper order, followed by a null
* @param s the stream
*/ */
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException { throws java.io.IOException {
...@@ -1177,9 +1175,7 @@ public class LinkedBlockingDeque<E> ...@@ -1177,9 +1175,7 @@ public class LinkedBlockingDeque<E>
} }
/** /**
* Reconstitute this deque from a stream (that is, * Reconstitutes this deque from a stream (that is, deserializes it).
* deserialize it).
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
......
...@@ -73,7 +73,6 @@ import java.util.NoSuchElementException; ...@@ -73,7 +73,6 @@ import java.util.NoSuchElementException;
* @since 1.5 * @since 1.5
* @author Doug Lea * @author Doug Lea
* @param <E> the type of elements held in this collection * @param <E> the type of elements held in this collection
*
*/ */
public class LinkedBlockingQueue<E> extends AbstractQueue<E> public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable { implements BlockingQueue<E>, java.io.Serializable {
...@@ -135,13 +134,13 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E> ...@@ -135,13 +134,13 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
private final int capacity; private final int capacity;
/** Current number of elements */ /** Current number of elements */
private final AtomicInteger count = new AtomicInteger(0); private final AtomicInteger count = new AtomicInteger();
/** /**
* Head of linked list. * Head of linked list.
* Invariant: head.item == null * Invariant: head.item == null
*/ */
private transient Node<E> head; transient Node<E> head;
/** /**
* Tail of linked list. * Tail of linked list.
...@@ -291,7 +290,6 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E> ...@@ -291,7 +290,6 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
} }
} }
// this doc comment is overridden to remove the reference to collections // this doc comment is overridden to remove the reference to collections
// greater in size than Integer.MAX_VALUE // greater in size than Integer.MAX_VALUE
/** /**
...@@ -430,7 +428,6 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E> ...@@ -430,7 +428,6 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
return c >= 0; return c >= 0;
} }
public E take() throws InterruptedException { public E take() throws InterruptedException {
E x; E x;
int c = -1; int c = -1;
...@@ -630,8 +627,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E> ...@@ -630,8 +627,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
* The following code can be used to dump the queue into a newly * The following code can be used to dump the queue into a newly
* allocated array of {@code String}: * allocated array of {@code String}:
* *
* <pre> * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
* String[] y = x.toArray(new String[0]);</pre>
* *
* Note that {@code toArray(new Object[0])} is identical in function to * Note that {@code toArray(new Object[0])} is identical in function to
* {@code toArray()}. * {@code toArray()}.
...@@ -860,12 +856,11 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E> ...@@ -860,12 +856,11 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
} }
/** /**
* Save the state to a stream (that is, serialize it). * Saves this queue to a stream (that is, serializes it).
* *
* @serialData The capacity is emitted (int), followed by all of * @serialData The capacity is emitted (int), followed by all of
* its elements (each an {@code Object}) in the proper order, * its elements (each an {@code Object}) in the proper order,
* followed by a null * followed by a null
* @param s the stream
*/ */
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException { throws java.io.IOException {
...@@ -887,10 +882,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E> ...@@ -887,10 +882,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
} }
/** /**
* Reconstitute this queue instance from a stream (that is, * Reconstitutes this queue from a stream (that is, deserializes it).
* deserialize it).
*
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
......
...@@ -695,7 +695,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E> ...@@ -695,7 +695,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
* @return matched item, or e if unmatched on interrupt or timeout * @return matched item, or e if unmatched on interrupt or timeout
*/ */
private E awaitMatch(Node s, Node pred, E e, boolean timed, long nanos) { private E awaitMatch(Node s, Node pred, E e, boolean timed, long nanos) {
long lastTime = timed ? System.nanoTime() : 0L; final long deadline = timed ? System.nanoTime() + nanos : 0L;
Thread w = Thread.currentThread(); Thread w = Thread.currentThread();
int spins = -1; // initialized after first item and cancel checks int spins = -1; // initialized after first item and cancel checks
ThreadLocalRandom randomYields = null; // bound if needed ThreadLocalRandom randomYields = null; // bound if needed
...@@ -726,10 +726,9 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E> ...@@ -726,10 +726,9 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
s.waiter = w; // request unpark then recheck s.waiter = w; // request unpark then recheck
} }
else if (timed) { else if (timed) {
long now = System.nanoTime(); nanos = deadline - System.nanoTime();
if ((nanos -= now - lastTime) > 0) if (nanos > 0L)
LockSupport.parkNanos(this, nanos); LockSupport.parkNanos(this, nanos);
lastTime = now;
} }
else { else {
LockSupport.park(this); LockSupport.park(this);
...@@ -1294,11 +1293,10 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E> ...@@ -1294,11 +1293,10 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
} }
/** /**
* Saves the state to a stream (that is, serializes it). * Saves this queue to a stream (that is, serializes it).
* *
* @serialData All of the elements (each an {@code E}) in * @serialData All of the elements (each an {@code E}) in
* the proper order, followed by a null * the proper order, followed by a null
* @param s the stream
*/ */
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException { throws java.io.IOException {
...@@ -1310,10 +1308,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E> ...@@ -1310,10 +1308,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
} }
/** /**
* Reconstitutes the Queue instance from a stream (that is, * Reconstitutes this queue from a stream (that is, deserializes it).
* deserializes it).
*
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
......
...@@ -39,37 +39,49 @@ package java.util.concurrent; ...@@ -39,37 +39,49 @@ package java.util.concurrent;
* A recursive resultless {@link ForkJoinTask}. This class * A recursive resultless {@link ForkJoinTask}. This class
* establishes conventions to parameterize resultless actions as * establishes conventions to parameterize resultless actions as
* {@code Void} {@code ForkJoinTask}s. Because {@code null} is the * {@code Void} {@code ForkJoinTask}s. Because {@code null} is the
* only valid value of type {@code Void}, methods such as join always * only valid value of type {@code Void}, methods such as {@code join}
* return {@code null} upon completion. * always return {@code null} upon completion.
* *
* <p><b>Sample Usages.</b> Here is a sketch of a ForkJoin sort that * <p><b>Sample Usages.</b> Here is a simple but complete ForkJoin
* sorts a given {@code long[]} array: * sort that sorts a given {@code long[]} array:
* *
* <pre> {@code * <pre> {@code
* class SortTask extends RecursiveAction { * static class SortTask extends RecursiveAction {
* final long[] array; final int lo; final int hi; * final long[] array; final int lo, hi;
* SortTask(long[] array, int lo, int hi) { * SortTask(long[] array, int lo, int hi) {
* this.array = array; this.lo = lo; this.hi = hi; * this.array = array; this.lo = lo; this.hi = hi;
* } * }
* SortTask(long[] array) { this(array, 0, array.length); }
* protected void compute() { * protected void compute() {
* if (hi - lo < THRESHOLD) * if (hi - lo < THRESHOLD)
* sequentiallySort(array, lo, hi); * sortSequentially(lo, hi);
* else { * else {
* int mid = (lo + hi) >>> 1; * int mid = (lo + hi) >>> 1;
* invokeAll(new SortTask(array, lo, mid), * invokeAll(new SortTask(array, lo, mid),
* new SortTask(array, mid, hi)); * new SortTask(array, mid, hi));
* merge(array, lo, hi); * merge(lo, mid, hi);
* } * }
* } * }
* // implementation details follow:
* final static int THRESHOLD = 1000;
* void sortSequentially(int lo, int hi) {
* Arrays.sort(array, lo, hi);
* }
* void merge(int lo, int mid, int hi) {
* long[] buf = Arrays.copyOfRange(array, lo, mid);
* for (int i = 0, j = lo, k = mid; i < buf.length; j++)
* array[j] = (k == hi || buf[i] < array[k]) ?
* buf[i++] : array[k++];
* }
* }}</pre> * }}</pre>
* *
* You could then sort {@code anArray} by creating {@code new * You could then sort {@code anArray} by creating {@code new
* SortTask(anArray, 0, anArray.length-1) } and invoking it in a * SortTask(anArray)} and invoking it in a ForkJoinPool. As a more
* ForkJoinPool. As a more concrete simple example, the following * concrete simple example, the following task increments each element
* task increments each element of an array: * of an array:
* <pre> {@code * <pre> {@code
* class IncrementTask extends RecursiveAction { * class IncrementTask extends RecursiveAction {
* final long[] array; final int lo; final int hi; * final long[] array; final int lo, hi;
* IncrementTask(long[] array, int lo, int hi) { * IncrementTask(long[] array, int lo, int hi) {
* this.array = array; this.lo = lo; this.hi = hi; * this.array = array; this.lo = lo; this.hi = hi;
* } * }
......
...@@ -78,8 +78,8 @@ public class RejectedExecutionException extends RuntimeException { ...@@ -78,8 +78,8 @@ public class RejectedExecutionException extends RuntimeException {
/** /**
* Constructs a <tt>RejectedExecutionException</tt> with the * Constructs a <tt>RejectedExecutionException</tt> with the
* specified cause. The detail message is set to: <pre> (cause == * specified cause. The detail message is set to {@code (cause ==
* null ? null : cause.toString())</pre> (which typically contains * null ? null : cause.toString())} (which typically contains
* the class and detail message of <tt>cause</tt>). * the class and detail message of <tt>cause</tt>).
* *
* @param cause the cause (which is saved for later retrieval by the * @param cause the cause (which is saved for later retrieval by the
......
...@@ -34,8 +34,6 @@ ...@@ -34,8 +34,6 @@
*/ */
package java.util.concurrent; package java.util.concurrent;
import java.util.concurrent.atomic.*;
import java.util.*;
/** /**
* An {@link ExecutorService} that can schedule commands to run after a given * An {@link ExecutorService} that can schedule commands to run after a given
......
...@@ -223,7 +223,7 @@ public class ScheduledThreadPoolExecutor ...@@ -223,7 +223,7 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* Creates a one-shot action with given nanoTime-based trigger. * Creates a one-shot action with given nanoTime-based trigger time.
*/ */
ScheduledFutureTask(Callable<V> callable, long ns) { ScheduledFutureTask(Callable<V> callable, long ns) {
super(callable); super(callable);
...@@ -237,7 +237,7 @@ public class ScheduledThreadPoolExecutor ...@@ -237,7 +237,7 @@ public class ScheduledThreadPoolExecutor
} }
public int compareTo(Delayed other) { public int compareTo(Delayed other) {
if (other == this) // compare zero ONLY if same object if (other == this) // compare zero if same object
return 0; return 0;
if (other instanceof ScheduledFutureTask) { if (other instanceof ScheduledFutureTask) {
ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other; ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
...@@ -251,9 +251,8 @@ public class ScheduledThreadPoolExecutor ...@@ -251,9 +251,8 @@ public class ScheduledThreadPoolExecutor
else else
return 1; return 1;
} }
long d = (getDelay(NANOSECONDS) - long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
other.getDelay(NANOSECONDS)); return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
} }
/** /**
...@@ -862,7 +861,7 @@ public class ScheduledThreadPoolExecutor ...@@ -862,7 +861,7 @@ public class ScheduledThreadPoolExecutor
private final Condition available = lock.newCondition(); private final Condition available = lock.newCondition();
/** /**
* Set f's heapIndex if it is a ScheduledFutureTask. * Sets f's heapIndex if it is a ScheduledFutureTask.
*/ */
private void setIndex(RunnableScheduledFuture<?> f, int idx) { private void setIndex(RunnableScheduledFuture<?> f, int idx) {
if (f instanceof ScheduledFutureTask) if (f instanceof ScheduledFutureTask)
...@@ -870,7 +869,7 @@ public class ScheduledThreadPoolExecutor ...@@ -870,7 +869,7 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* Sift element added at bottom up to its heap-ordered spot. * Sifts element added at bottom up to its heap-ordered spot.
* Call only when holding lock. * Call only when holding lock.
*/ */
private void siftUp(int k, RunnableScheduledFuture<?> key) { private void siftUp(int k, RunnableScheduledFuture<?> key) {
...@@ -888,7 +887,7 @@ public class ScheduledThreadPoolExecutor ...@@ -888,7 +887,7 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* Sift element added at top down to its heap-ordered spot. * Sifts element added at top down to its heap-ordered spot.
* Call only when holding lock. * Call only when holding lock.
*/ */
private void siftDown(int k, RunnableScheduledFuture<?> key) { private void siftDown(int k, RunnableScheduledFuture<?> key) {
...@@ -910,7 +909,7 @@ public class ScheduledThreadPoolExecutor ...@@ -910,7 +909,7 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* Resize the heap array. Call only when holding lock. * Resizes the heap array. Call only when holding lock.
*/ */
private void grow() { private void grow() {
int oldCapacity = queue.length; int oldCapacity = queue.length;
...@@ -921,7 +920,7 @@ public class ScheduledThreadPoolExecutor ...@@ -921,7 +920,7 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* Find index of given object, or -1 if absent * Finds index of given object, or -1 if absent.
*/ */
private int indexOf(Object x) { private int indexOf(Object x) {
if (x != null) { if (x != null) {
...@@ -1162,15 +1161,14 @@ public class ScheduledThreadPoolExecutor ...@@ -1162,15 +1161,14 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* Return and remove first element only if it is expired. * Returns first element only if it is expired.
* Used only by drainTo. Call only when holding lock. * Used only by drainTo. Call only when holding lock.
*/ */
private RunnableScheduledFuture<?> pollExpired() { private RunnableScheduledFuture<?> peekExpired() {
// assert lock.isHeldByCurrentThread(); // assert lock.isHeldByCurrentThread();
RunnableScheduledFuture<?> first = queue[0]; RunnableScheduledFuture<?> first = queue[0];
if (first == null || first.getDelay(NANOSECONDS) > 0) return (first == null || first.getDelay(NANOSECONDS) > 0) ?
return null; null : first;
return finishPoll(first);
} }
public int drainTo(Collection<? super Runnable> c) { public int drainTo(Collection<? super Runnable> c) {
...@@ -1183,8 +1181,9 @@ public class ScheduledThreadPoolExecutor ...@@ -1183,8 +1181,9 @@ public class ScheduledThreadPoolExecutor
try { try {
RunnableScheduledFuture<?> first; RunnableScheduledFuture<?> first;
int n = 0; int n = 0;
while ((first = pollExpired()) != null) { while ((first = peekExpired()) != null) {
c.add(first); c.add(first); // In this order, in case add() throws.
finishPoll(first);
++n; ++n;
} }
return n; return n;
...@@ -1205,8 +1204,9 @@ public class ScheduledThreadPoolExecutor ...@@ -1205,8 +1204,9 @@ public class ScheduledThreadPoolExecutor
try { try {
RunnableScheduledFuture<?> first; RunnableScheduledFuture<?> first;
int n = 0; int n = 0;
while (n < maxElements && (first = pollExpired()) != null) { while (n < maxElements && (first = peekExpired()) != null) {
c.add(first); c.add(first); // In this order, in case add() throws.
finishPoll(first);
++n; ++n;
} }
return n; return n;
......
...@@ -34,9 +34,8 @@ ...@@ -34,9 +34,8 @@
*/ */
package java.util.concurrent; package java.util.concurrent;
import java.util.*; import java.util.Collection;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.atomic.*;
/** /**
* A counting semaphore. Conceptually, a semaphore maintains a set of * A counting semaphore. Conceptually, a semaphore maintains a set of
...@@ -49,7 +48,7 @@ import java.util.concurrent.atomic.*; ...@@ -49,7 +48,7 @@ import java.util.concurrent.atomic.*;
* <p>Semaphores are often used to restrict the number of threads than can * <p>Semaphores are often used to restrict the number of threads than can
* access some (physical or logical) resource. For example, here is * access some (physical or logical) resource. For example, here is
* a class that uses a semaphore to control access to a pool of items: * a class that uses a semaphore to control access to a pool of items:
* <pre> * <pre> {@code
* class Pool { * class Pool {
* private static final int MAX_AVAILABLE = 100; * private static final int MAX_AVAILABLE = 100;
* private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); * private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
...@@ -91,9 +90,7 @@ import java.util.concurrent.atomic.*; ...@@ -91,9 +90,7 @@ import java.util.concurrent.atomic.*;
* } * }
* return false; * return false;
* } * }
* * }}</pre>
* }
* </pre>
* *
* <p>Before obtaining an item each thread must acquire a permit from * <p>Before obtaining an item each thread must acquire a permit from
* the semaphore, guaranteeing that an item is available for use. When * the semaphore, guaranteeing that an item is available for use. When
...@@ -111,7 +108,7 @@ import java.util.concurrent.atomic.*; ...@@ -111,7 +108,7 @@ import java.util.concurrent.atomic.*;
* exclusion lock. This is more commonly known as a <em>binary * exclusion lock. This is more commonly known as a <em>binary
* semaphore</em>, because it only has two states: one permit * semaphore</em>, because it only has two states: one permit
* available, or zero permits available. When used in this way, the * available, or zero permits available. When used in this way, the
* binary semaphore has the property (unlike many {@link Lock} * binary semaphore has the property (unlike many {@link java.util.concurrent.locks.Lock}
* implementations), that the &quot;lock&quot; can be released by a * implementations), that the &quot;lock&quot; can be released by a
* thread other than the owner (as semaphores have no notion of * thread other than the owner (as semaphores have no notion of
* ownership). This can be useful in some specialized contexts, such * ownership). This can be useful in some specialized contexts, such
...@@ -155,9 +152,7 @@ import java.util.concurrent.atomic.*; ...@@ -155,9 +152,7 @@ import java.util.concurrent.atomic.*;
* *
* @since 1.5 * @since 1.5
* @author Doug Lea * @author Doug Lea
*
*/ */
public class Semaphore implements java.io.Serializable { public class Semaphore implements java.io.Serializable {
private static final long serialVersionUID = -3222578661600680210L; private static final long serialVersionUID = -3222578661600680210L;
/** All mechanics via AbstractQueuedSynchronizer subclass */ /** All mechanics via AbstractQueuedSynchronizer subclass */
...@@ -493,7 +488,6 @@ public class Semaphore implements java.io.Serializable { ...@@ -493,7 +488,6 @@ public class Semaphore implements java.io.Serializable {
* *
* @param permits the number of permits to acquire * @param permits the number of permits to acquire
* @throws IllegalArgumentException if {@code permits} is negative * @throws IllegalArgumentException if {@code permits} is negative
*
*/ */
public void acquireUninterruptibly(int permits) { public void acquireUninterruptibly(int permits) {
if (permits < 0) throw new IllegalArgumentException(); if (permits < 0) throw new IllegalArgumentException();
......
...@@ -35,7 +35,8 @@ ...@@ -35,7 +35,8 @@
*/ */
package java.util.concurrent; package java.util.concurrent;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
import java.util.*; import java.util.*;
/** /**
...@@ -222,7 +223,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -222,7 +223,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
/** Node is fulfilling another unfulfilled DATA or REQUEST */ /** Node is fulfilling another unfulfilled DATA or REQUEST */
static final int FULFILLING = 2; static final int FULFILLING = 2;
/** Return true if m has fulfilling bit set */ /** Returns true if m has fulfilling bit set. */
static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; } static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; }
/** Node class for TransferStacks. */ /** Node class for TransferStacks. */
...@@ -430,9 +431,8 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -430,9 +431,8 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
* and don't wait at all, so are trapped in transfer * and don't wait at all, so are trapped in transfer
* method rather than calling awaitFulfill. * method rather than calling awaitFulfill.
*/ */
long lastTime = timed ? System.nanoTime() : 0; final long deadline = timed ? System.nanoTime() + nanos : 0L;
Thread w = Thread.currentThread(); Thread w = Thread.currentThread();
SNode h = head;
int spins = (shouldSpin(s) ? int spins = (shouldSpin(s) ?
(timed ? maxTimedSpins : maxUntimedSpins) : 0); (timed ? maxTimedSpins : maxUntimedSpins) : 0);
for (;;) { for (;;) {
...@@ -442,10 +442,8 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -442,10 +442,8 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
if (m != null) if (m != null)
return m; return m;
if (timed) { if (timed) {
long now = System.nanoTime(); nanos = deadline - System.nanoTime();
nanos -= now - lastTime; if (nanos <= 0L) {
lastTime = now;
if (nanos <= 0) {
s.tryCancel(); s.tryCancel();
continue; continue;
} }
...@@ -737,7 +735,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -737,7 +735,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
*/ */
Object awaitFulfill(QNode s, E e, boolean timed, long nanos) { Object awaitFulfill(QNode s, E e, boolean timed, long nanos) {
/* Same idea as TransferStack.awaitFulfill */ /* Same idea as TransferStack.awaitFulfill */
long lastTime = timed ? System.nanoTime() : 0; final long deadline = timed ? System.nanoTime() + nanos : 0L;
Thread w = Thread.currentThread(); Thread w = Thread.currentThread();
int spins = ((head.next == s) ? int spins = ((head.next == s) ?
(timed ? maxTimedSpins : maxUntimedSpins) : 0); (timed ? maxTimedSpins : maxUntimedSpins) : 0);
...@@ -748,10 +746,8 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -748,10 +746,8 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
if (x != e) if (x != e)
return x; return x;
if (timed) { if (timed) {
long now = System.nanoTime(); nanos = deadline - System.nanoTime();
nanos -= now - lastTime; if (nanos <= 0L) {
lastTime = now;
if (nanos <= 0) {
s.tryCancel(e); s.tryCancel(e);
continue; continue;
} }
...@@ -874,9 +870,9 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -874,9 +870,9 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
* @throws InterruptedException {@inheritDoc} * @throws InterruptedException {@inheritDoc}
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
*/ */
public void put(E o) throws InterruptedException { public void put(E e) throws InterruptedException {
if (o == null) throw new NullPointerException(); if (e == null) throw new NullPointerException();
if (transferer.transfer(o, false, 0) == null) { if (transferer.transfer(e, false, 0) == null) {
Thread.interrupted(); Thread.interrupted();
throw new InterruptedException(); throw new InterruptedException();
} }
...@@ -891,10 +887,10 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -891,10 +887,10 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
* @throws InterruptedException {@inheritDoc} * @throws InterruptedException {@inheritDoc}
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
*/ */
public boolean offer(E o, long timeout, TimeUnit unit) public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
if (o == null) throw new NullPointerException(); if (e == null) throw new NullPointerException();
if (transferer.transfer(o, true, unit.toNanos(timeout)) != null) if (transferer.transfer(e, true, unit.toNanos(timeout)) != null)
return true; return true;
if (!Thread.interrupted()) if (!Thread.interrupted())
return false; return false;
...@@ -1162,9 +1158,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -1162,9 +1158,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
private WaitQueue waitingConsumers; private WaitQueue waitingConsumers;
/** /**
* Saves the state to a stream (that is, serializes it). * Saves this queue to a stream (that is, serializes it).
*
* @param s the stream
*/ */
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException { throws java.io.IOException {
...@@ -1182,6 +1176,9 @@ public class SynchronousQueue<E> extends AbstractQueue<E> ...@@ -1182,6 +1176,9 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
s.defaultWriteObject(); s.defaultWriteObject();
} }
/**
* Reconstitutes this queue from a stream (that is, deserializes it).
*/
private void readObject(final java.io.ObjectInputStream s) private void readObject(final java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject(); s.defaultReadObject();
......
...@@ -42,13 +42,12 @@ package java.util.concurrent; ...@@ -42,13 +42,12 @@ package java.util.concurrent;
* *
* <p> * <p>
* The simplest implementation of this interface is just: * The simplest implementation of this interface is just:
* <pre> * <pre> {@code
* class SimpleThreadFactory implements ThreadFactory { * class SimpleThreadFactory implements ThreadFactory {
* public Thread newThread(Runnable r) { * public Thread newThread(Runnable r) {
* return new Thread(r); * return new Thread(r);
* } * }
* } * }}</pre>
* </pre>
* *
* The {@link Executors#defaultThreadFactory} method provides a more * The {@link Executors#defaultThreadFactory} method provides a more
* useful simple implementation, that sets the created thread context * useful simple implementation, that sets the created thread context
......
...@@ -52,14 +52,14 @@ package java.util.concurrent; ...@@ -52,14 +52,14 @@ package java.util.concurrent;
* the following code will timeout in 50 milliseconds if the {@link * the following code will timeout in 50 milliseconds if the {@link
* java.util.concurrent.locks.Lock lock} is not available: * java.util.concurrent.locks.Lock lock} is not available:
* *
* <pre> Lock lock = ...; * <pre> {@code
* if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ... * Lock lock = ...;
* </pre> * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...}</pre>
*
* while this code will timeout in 50 seconds: * while this code will timeout in 50 seconds:
* <pre> * <pre> {@code
* Lock lock = ...; * Lock lock = ...;
* if (lock.tryLock(50L, TimeUnit.SECONDS)) ... * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...}</pre>
* </pre>
* *
* Note however, that there is no guarantee that a particular timeout * Note however, that there is no guarantee that a particular timeout
* implementation will be able to notice the passage of time at the * implementation will be able to notice the passage of time at the
......
...@@ -245,7 +245,6 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -245,7 +245,6 @@ public class AtomicInteger extends Number implements java.io.Serializable {
return Integer.toString(get()); return Integer.toString(get());
} }
/** /**
* Returns the value of this {@code AtomicInteger} as an {@code int}. * Returns the value of this {@code AtomicInteger} as an {@code int}.
*/ */
......
...@@ -274,9 +274,9 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -274,9 +274,9 @@ public abstract class AtomicIntegerFieldUpdater<T> {
private final Class<?> cclass; private final Class<?> cclass;
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) { AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) {
Field field = null; final Field field;
Class<?> caller = null; final Class<?> caller;
int modifiers = 0; final int modifiers;
try { try {
field = AccessController.doPrivileged( field = AccessController.doPrivileged(
new PrivilegedExceptionAction<Field>() { new PrivilegedExceptionAction<Field>() {
......
...@@ -259,7 +259,6 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -259,7 +259,6 @@ public class AtomicLong extends Number implements java.io.Serializable {
return Long.toString(get()); return Long.toString(get());
} }
/** /**
* Returns the value of this {@code AtomicLong} as an {@code int} * Returns the value of this {@code AtomicLong} as an {@code int}
* after a narrowing primitive conversion. * after a narrowing primitive conversion.
......
...@@ -274,9 +274,9 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -274,9 +274,9 @@ public abstract class AtomicLongFieldUpdater<T> {
private final Class<?> cclass; private final Class<?> cclass;
CASUpdater(final Class<T> tclass, final String fieldName) { CASUpdater(final Class<T> tclass, final String fieldName) {
Field field = null; final Field field;
Class<?> caller = null; final Class<?> caller;
int modifiers = 0; final int modifiers;
try { try {
field = AccessController.doPrivileged( field = AccessController.doPrivileged(
new PrivilegedExceptionAction<Field>() { new PrivilegedExceptionAction<Field>() {
......
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
package java.util.concurrent.atomic; package java.util.concurrent.atomic;
import java.lang.reflect.Array;
import java.util.Arrays; import java.util.Arrays;
import java.lang.reflect.Array;
import sun.misc.Unsafe; import sun.misc.Unsafe;
/** /**
...@@ -151,7 +151,6 @@ public class AtomicReferenceArray<E> implements java.io.Serializable { ...@@ -151,7 +151,6 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
unsafe.putOrderedObject(array, checkedByteOffset(i), newValue); unsafe.putOrderedObject(array, checkedByteOffset(i), newValue);
} }
/** /**
* Atomically sets the element at position {@code i} to the given * Atomically sets the element at position {@code i} to the given
* value and returns the old value. * value and returns the old value.
...@@ -225,10 +224,10 @@ public class AtomicReferenceArray<E> implements java.io.Serializable { ...@@ -225,10 +224,10 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
/** /**
* Reconstitutes the instance from a stream (that is, deserializes it). * Reconstitutes the instance from a stream (that is, deserializes it).
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException,
java.io.InvalidObjectException {
// Note: This must be changed if any additional fields are defined // Note: This must be changed if any additional fields are defined
Object a = s.readFields().get("array", null); Object a = s.readFields().get("array", null);
if (a == null || !a.getClass().isArray()) if (a == null || !a.getClass().isArray())
......
...@@ -206,10 +206,10 @@ public abstract class AtomicReferenceFieldUpdater<T, V> { ...@@ -206,10 +206,10 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
AtomicReferenceFieldUpdaterImpl(final Class<T> tclass, AtomicReferenceFieldUpdaterImpl(final Class<T> tclass,
Class<V> vclass, Class<V> vclass,
final String fieldName) { final String fieldName) {
Field field = null; final Field field;
Class<?> fieldClass = null; final Class<?> fieldClass;
Class<?> caller = null; final Class<?> caller;
int modifiers = 0; final int modifiers;
try { try {
field = AccessController.doPrivileged( field = AccessController.doPrivileged(
new PrivilegedExceptionAction<Field>() { new PrivilegedExceptionAction<Field>() {
......
...@@ -40,9 +40,7 @@ ...@@ -40,9 +40,7 @@
* array elements to those that also provide an atomic conditional update * array elements to those that also provide an atomic conditional update
* operation of the form: * operation of the form:
* *
* <pre> * <pre> {@code boolean compareAndSet(expectedValue, updateValue);}</pre>
* boolean compareAndSet(expectedValue, updateValue);
* </pre>
* *
* <p>This method (which varies in argument types across different * <p>This method (which varies in argument types across different
* classes) atomically sets a variable to the {@code updateValue} if it * classes) atomically sets a variable to the {@code updateValue} if it
...@@ -69,19 +67,36 @@ ...@@ -69,19 +67,36 @@
* {@code AtomicInteger} provide atomic increment methods. One * {@code AtomicInteger} provide atomic increment methods. One
* application is to generate sequence numbers, as in: * application is to generate sequence numbers, as in:
* *
* <pre> * <pre> {@code
* class Sequencer { * class Sequencer {
* private final AtomicLong sequenceNumber * private final AtomicLong sequenceNumber
* = new AtomicLong(0); * = new AtomicLong(0);
* public long next() { * public long next() {
* return sequenceNumber.getAndIncrement(); * return sequenceNumber.getAndIncrement();
* } * }
* }}</pre>
*
* <p>It is straightforward to define new utility functions that, like
* {@code getAndIncrement}, apply a function to a value atomically.
* For example, given some transformation
* <pre> {@code long transform(long input)}</pre>
*
* write your utility method as follows:
* <pre> {@code
* long getAndTransform(AtomicLong var) {
* while (true) {
* long current = var.get();
* long next = transform(current);
* if (var.compareAndSet(current, next))
* return current;
* // return next; for transformAndGet
* } * }
* </pre> * }}</pre>
* *
* <p>The memory effects for accesses and updates of atomics generally * <p>The memory effects for accesses and updates of atomics generally
* follow the rules for volatiles, as stated in section 17.4 of * follow the rules for volatiles, as stated in
* <cite>The Java&trade; Language Specification</cite>. * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/index.html">
* The Java Language Specification, Third Edition (17.4 Memory Model)</a>:
* *
* <ul> * <ul>
* *
...@@ -189,9 +204,9 @@ ...@@ -189,9 +204,9 @@
* {@code byte} values, and cast appropriately. * {@code byte} values, and cast appropriately.
* *
* You can also hold floats using * You can also hold floats using
* {@link java.lang.Float#floatToIntBits} and * {@link java.lang.Float#floatToRawIntBits} and
* {@link java.lang.Float#intBitsToFloat} conversions, and doubles using * {@link java.lang.Float#intBitsToFloat} conversions, and doubles using
* {@link java.lang.Double#doubleToLongBits} and * {@link java.lang.Double#doubleToRawLongBits} and
* {@link java.lang.Double#longBitsToDouble} conversions. * {@link java.lang.Double#longBitsToDouble} conversions.
* *
* @since 1.5 * @since 1.5
......
...@@ -34,9 +34,10 @@ ...@@ -34,9 +34,10 @@
*/ */
package java.util.concurrent.locks; package java.util.concurrent.locks;
import java.util.*; import java.util.concurrent.TimeUnit;
import java.util.concurrent.*; import java.util.ArrayList;
import java.util.concurrent.atomic.*; import java.util.Collection;
import java.util.Date;
import sun.misc.Unsafe; import sun.misc.Unsafe;
/** /**
...@@ -598,7 +599,7 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -598,7 +599,7 @@ public abstract class AbstractQueuedLongSynchronizer
/** /**
* Convenience method to interrupt current thread. * Convenience method to interrupt current thread.
*/ */
private static void selfInterrupt() { static void selfInterrupt() {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
...@@ -687,7 +688,9 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -687,7 +688,9 @@ public abstract class AbstractQueuedLongSynchronizer
*/ */
private boolean doAcquireNanos(long arg, long nanosTimeout) private boolean doAcquireNanos(long arg, long nanosTimeout)
throws InterruptedException { throws InterruptedException {
long lastTime = System.nanoTime(); if (nanosTimeout <= 0L)
return false;
final long deadline = System.nanoTime() + nanosTimeout;
final Node node = addWaiter(Node.EXCLUSIVE); final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true; boolean failed = true;
try { try {
...@@ -699,14 +702,12 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -699,14 +702,12 @@ public abstract class AbstractQueuedLongSynchronizer
failed = false; failed = false;
return true; return true;
} }
if (nanosTimeout <= 0) nanosTimeout = deadline - System.nanoTime();
if (nanosTimeout <= 0L)
return false; return false;
if (shouldParkAfterFailedAcquire(p, node) && if (shouldParkAfterFailedAcquire(p, node) &&
nanosTimeout > spinForTimeoutThreshold) nanosTimeout > spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout); LockSupport.parkNanos(this, nanosTimeout);
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
if (Thread.interrupted()) if (Thread.interrupted())
throw new InterruptedException(); throw new InterruptedException();
} }
...@@ -787,8 +788,9 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -787,8 +788,9 @@ public abstract class AbstractQueuedLongSynchronizer
*/ */
private boolean doAcquireSharedNanos(long arg, long nanosTimeout) private boolean doAcquireSharedNanos(long arg, long nanosTimeout)
throws InterruptedException { throws InterruptedException {
if (nanosTimeout <= 0L)
long lastTime = System.nanoTime(); return false;
final long deadline = System.nanoTime() + nanosTimeout;
final Node node = addWaiter(Node.SHARED); final Node node = addWaiter(Node.SHARED);
boolean failed = true; boolean failed = true;
try { try {
...@@ -803,14 +805,12 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -803,14 +805,12 @@ public abstract class AbstractQueuedLongSynchronizer
return true; return true;
} }
} }
if (nanosTimeout <= 0) nanosTimeout = deadline - System.nanoTime();
if (nanosTimeout <= 0L)
return false; return false;
if (shouldParkAfterFailedAcquire(p, node) && if (shouldParkAfterFailedAcquire(p, node) &&
nanosTimeout > spinForTimeoutThreshold) nanosTimeout > spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout); LockSupport.parkNanos(this, nanosTimeout);
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
if (Thread.interrupted()) if (Thread.interrupted())
throw new InterruptedException(); throw new InterruptedException();
} }
...@@ -1260,7 +1260,7 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1260,7 +1260,7 @@ public abstract class AbstractQueuedLongSynchronizer
* due to the queue being empty. * due to the queue being empty.
* *
* <p>This method is designed to be used by a fair synchronizer to * <p>This method is designed to be used by a fair synchronizer to
* avoid <a href="AbstractQueuedSynchronizer#barging">barging</a>. * avoid <a href="AbstractQueuedSynchronizer.html#barging">barging</a>.
* Such a synchronizer's {@link #tryAcquire} method should return * Such a synchronizer's {@link #tryAcquire} method should return
* {@code false}, and its {@link #tryAcquireShared} method should * {@code false}, and its {@link #tryAcquireShared} method should
* return a negative value, if this method returns {@code true} * return a negative value, if this method returns {@code true}
...@@ -1520,8 +1520,6 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1520,8 +1520,6 @@ public abstract class AbstractQueuedLongSynchronizer
* @throws NullPointerException if the condition is null * @throws NullPointerException if the condition is null
*/ */
public final boolean owns(ConditionObject condition) { public final boolean owns(ConditionObject condition) {
if (condition == null)
throw new NullPointerException();
return condition.isOwnedBy(this); return condition.isOwnedBy(this);
} }
...@@ -1742,9 +1740,8 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1742,9 +1740,8 @@ public abstract class AbstractQueuedLongSynchronizer
* Implements uninterruptible condition wait. * Implements uninterruptible condition wait.
* <ol> * <ol>
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled. * <li> Block until signalled.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -1803,9 +1800,8 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1803,9 +1800,8 @@ public abstract class AbstractQueuedLongSynchronizer
* <ol> * <ol>
* <li> If current thread is interrupted, throw InterruptedException. * <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled or interrupted. * <li> Block until signalled or interrupted.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -1836,9 +1832,8 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1836,9 +1832,8 @@ public abstract class AbstractQueuedLongSynchronizer
* <ol> * <ol>
* <li> If current thread is interrupted, throw InterruptedException. * <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled, interrupted, or timed out. * <li> Block until signalled, interrupted, or timed out.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -1851,20 +1846,18 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1851,20 +1846,18 @@ public abstract class AbstractQueuedLongSynchronizer
throw new InterruptedException(); throw new InterruptedException();
Node node = addConditionWaiter(); Node node = addConditionWaiter();
long savedState = fullyRelease(node); long savedState = fullyRelease(node);
long lastTime = System.nanoTime(); final long deadline = System.nanoTime() + nanosTimeout;
int interruptMode = 0; int interruptMode = 0;
while (!isOnSyncQueue(node)) { while (!isOnSyncQueue(node)) {
if (nanosTimeout <= 0L) { if (nanosTimeout <= 0L) {
transferAfterCancelledWait(node); transferAfterCancelledWait(node);
break; break;
} }
if (nanosTimeout >= spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout); LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break; break;
nanosTimeout = deadline - System.nanoTime();
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
} }
if (acquireQueued(node, savedState) && interruptMode != THROW_IE) if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT; interruptMode = REINTERRUPT;
...@@ -1872,7 +1865,7 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1872,7 +1865,7 @@ public abstract class AbstractQueuedLongSynchronizer
unlinkCancelledWaiters(); unlinkCancelledWaiters();
if (interruptMode != 0) if (interruptMode != 0)
reportInterruptAfterWait(interruptMode); reportInterruptAfterWait(interruptMode);
return nanosTimeout - (System.nanoTime() - lastTime); return deadline - System.nanoTime();
} }
/** /**
...@@ -1880,9 +1873,8 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1880,9 +1873,8 @@ public abstract class AbstractQueuedLongSynchronizer
* <ol> * <ol>
* <li> If current thread is interrupted, throw InterruptedException. * <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled, interrupted, or timed out. * <li> Block until signalled, interrupted, or timed out.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -1892,8 +1884,6 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1892,8 +1884,6 @@ public abstract class AbstractQueuedLongSynchronizer
*/ */
public final boolean awaitUntil(Date deadline) public final boolean awaitUntil(Date deadline)
throws InterruptedException { throws InterruptedException {
if (deadline == null)
throw new NullPointerException();
long abstime = deadline.getTime(); long abstime = deadline.getTime();
if (Thread.interrupted()) if (Thread.interrupted())
throw new InterruptedException(); throw new InterruptedException();
...@@ -1924,9 +1914,8 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1924,9 +1914,8 @@ public abstract class AbstractQueuedLongSynchronizer
* <ol> * <ol>
* <li> If current thread is interrupted, throw InterruptedException. * <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled, interrupted, or timed out. * <li> Block until signalled, interrupted, or timed out.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -1936,14 +1925,12 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1936,14 +1925,12 @@ public abstract class AbstractQueuedLongSynchronizer
*/ */
public final boolean await(long time, TimeUnit unit) public final boolean await(long time, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
if (unit == null)
throw new NullPointerException();
long nanosTimeout = unit.toNanos(time); long nanosTimeout = unit.toNanos(time);
if (Thread.interrupted()) if (Thread.interrupted())
throw new InterruptedException(); throw new InterruptedException();
Node node = addConditionWaiter(); Node node = addConditionWaiter();
long savedState = fullyRelease(node); long savedState = fullyRelease(node);
long lastTime = System.nanoTime(); final long deadline = System.nanoTime() + nanosTimeout;
boolean timedout = false; boolean timedout = false;
int interruptMode = 0; int interruptMode = 0;
while (!isOnSyncQueue(node)) { while (!isOnSyncQueue(node)) {
...@@ -1955,9 +1942,7 @@ public abstract class AbstractQueuedLongSynchronizer ...@@ -1955,9 +1942,7 @@ public abstract class AbstractQueuedLongSynchronizer
LockSupport.parkNanos(this, nanosTimeout); LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break; break;
long now = System.nanoTime(); nanosTimeout = deadline - System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
} }
if (acquireQueued(node, savedState) && interruptMode != THROW_IE) if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT; interruptMode = REINTERRUPT;
......
...@@ -34,9 +34,10 @@ ...@@ -34,9 +34,10 @@
*/ */
package java.util.concurrent.locks; package java.util.concurrent.locks;
import java.util.*; import java.util.concurrent.TimeUnit;
import java.util.concurrent.*; import java.util.ArrayList;
import java.util.concurrent.atomic.*; import java.util.Collection;
import java.util.Date;
import sun.misc.Unsafe; import sun.misc.Unsafe;
/** /**
...@@ -194,7 +195,7 @@ import sun.misc.Unsafe; ...@@ -194,7 +195,7 @@ import sun.misc.Unsafe;
* It also supports conditions and exposes * It also supports conditions and exposes
* one of the instrumentation methods: * one of the instrumentation methods:
* *
* <pre> * <pre> {@code
* class Mutex implements Lock, java.io.Serializable { * class Mutex implements Lock, java.io.Serializable {
* *
* // Our internal helper class * // Our internal helper class
...@@ -250,15 +251,15 @@ import sun.misc.Unsafe; ...@@ -250,15 +251,15 @@ import sun.misc.Unsafe;
* throws InterruptedException { * throws InterruptedException {
* return sync.tryAcquireNanos(1, unit.toNanos(timeout)); * return sync.tryAcquireNanos(1, unit.toNanos(timeout));
* } * }
* } * }}</pre>
* </pre>
* *
* <p>Here is a latch class that is like a {@link CountDownLatch} * <p>Here is a latch class that is like a
* {@link java.util.concurrent.CountDownLatch CountDownLatch}
* except that it only requires a single <tt>signal</tt> to * except that it only requires a single <tt>signal</tt> to
* fire. Because a latch is non-exclusive, it uses the <tt>shared</tt> * fire. Because a latch is non-exclusive, it uses the <tt>shared</tt>
* acquire and release methods. * acquire and release methods.
* *
* <pre> * <pre> {@code
* class BooleanLatch { * class BooleanLatch {
* *
* private static class Sync extends AbstractQueuedSynchronizer { * private static class Sync extends AbstractQueuedSynchronizer {
...@@ -280,8 +281,7 @@ import sun.misc.Unsafe; ...@@ -280,8 +281,7 @@ import sun.misc.Unsafe;
* public void await() throws InterruptedException { * public void await() throws InterruptedException {
* sync.acquireSharedInterruptibly(1); * sync.acquireSharedInterruptibly(1);
* } * }
* } * }}</pre>
* </pre>
* *
* @since 1.5 * @since 1.5
* @author Doug Lea * @author Doug Lea
...@@ -821,7 +821,7 @@ public abstract class AbstractQueuedSynchronizer ...@@ -821,7 +821,7 @@ public abstract class AbstractQueuedSynchronizer
/** /**
* Convenience method to interrupt current thread. * Convenience method to interrupt current thread.
*/ */
private static void selfInterrupt() { static void selfInterrupt() {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
...@@ -910,7 +910,9 @@ public abstract class AbstractQueuedSynchronizer ...@@ -910,7 +910,9 @@ public abstract class AbstractQueuedSynchronizer
*/ */
private boolean doAcquireNanos(int arg, long nanosTimeout) private boolean doAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException { throws InterruptedException {
long lastTime = System.nanoTime(); if (nanosTimeout <= 0L)
return false;
final long deadline = System.nanoTime() + nanosTimeout;
final Node node = addWaiter(Node.EXCLUSIVE); final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true; boolean failed = true;
try { try {
...@@ -922,14 +924,12 @@ public abstract class AbstractQueuedSynchronizer ...@@ -922,14 +924,12 @@ public abstract class AbstractQueuedSynchronizer
failed = false; failed = false;
return true; return true;
} }
if (nanosTimeout <= 0) nanosTimeout = deadline - System.nanoTime();
if (nanosTimeout <= 0L)
return false; return false;
if (shouldParkAfterFailedAcquire(p, node) && if (shouldParkAfterFailedAcquire(p, node) &&
nanosTimeout > spinForTimeoutThreshold) nanosTimeout > spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout); LockSupport.parkNanos(this, nanosTimeout);
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
if (Thread.interrupted()) if (Thread.interrupted())
throw new InterruptedException(); throw new InterruptedException();
} }
...@@ -1010,8 +1010,9 @@ public abstract class AbstractQueuedSynchronizer ...@@ -1010,8 +1010,9 @@ public abstract class AbstractQueuedSynchronizer
*/ */
private boolean doAcquireSharedNanos(int arg, long nanosTimeout) private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
throws InterruptedException { throws InterruptedException {
if (nanosTimeout <= 0L)
long lastTime = System.nanoTime(); return false;
final long deadline = System.nanoTime() + nanosTimeout;
final Node node = addWaiter(Node.SHARED); final Node node = addWaiter(Node.SHARED);
boolean failed = true; boolean failed = true;
try { try {
...@@ -1026,14 +1027,12 @@ public abstract class AbstractQueuedSynchronizer ...@@ -1026,14 +1027,12 @@ public abstract class AbstractQueuedSynchronizer
return true; return true;
} }
} }
if (nanosTimeout <= 0) nanosTimeout = deadline - System.nanoTime();
if (nanosTimeout <= 0L)
return false; return false;
if (shouldParkAfterFailedAcquire(p, node) && if (shouldParkAfterFailedAcquire(p, node) &&
nanosTimeout > spinForTimeoutThreshold) nanosTimeout > spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout); LockSupport.parkNanos(this, nanosTimeout);
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
if (Thread.interrupted()) if (Thread.interrupted())
throw new InterruptedException(); throw new InterruptedException();
} }
...@@ -1743,8 +1742,6 @@ public abstract class AbstractQueuedSynchronizer ...@@ -1743,8 +1742,6 @@ public abstract class AbstractQueuedSynchronizer
* @throws NullPointerException if the condition is null * @throws NullPointerException if the condition is null
*/ */
public final boolean owns(ConditionObject condition) { public final boolean owns(ConditionObject condition) {
if (condition == null)
throw new NullPointerException();
return condition.isOwnedBy(this); return condition.isOwnedBy(this);
} }
...@@ -1963,9 +1960,8 @@ public abstract class AbstractQueuedSynchronizer ...@@ -1963,9 +1960,8 @@ public abstract class AbstractQueuedSynchronizer
* Implements uninterruptible condition wait. * Implements uninterruptible condition wait.
* <ol> * <ol>
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled. * <li> Block until signalled.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -2024,9 +2020,8 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2024,9 +2020,8 @@ public abstract class AbstractQueuedSynchronizer
* <ol> * <ol>
* <li> If current thread is interrupted, throw InterruptedException. * <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled or interrupted. * <li> Block until signalled or interrupted.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -2057,9 +2052,8 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2057,9 +2052,8 @@ public abstract class AbstractQueuedSynchronizer
* <ol> * <ol>
* <li> If current thread is interrupted, throw InterruptedException. * <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled, interrupted, or timed out. * <li> Block until signalled, interrupted, or timed out.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -2072,20 +2066,18 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2072,20 +2066,18 @@ public abstract class AbstractQueuedSynchronizer
throw new InterruptedException(); throw new InterruptedException();
Node node = addConditionWaiter(); Node node = addConditionWaiter();
int savedState = fullyRelease(node); int savedState = fullyRelease(node);
long lastTime = System.nanoTime(); final long deadline = System.nanoTime() + nanosTimeout;
int interruptMode = 0; int interruptMode = 0;
while (!isOnSyncQueue(node)) { while (!isOnSyncQueue(node)) {
if (nanosTimeout <= 0L) { if (nanosTimeout <= 0L) {
transferAfterCancelledWait(node); transferAfterCancelledWait(node);
break; break;
} }
if (nanosTimeout >= spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout); LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break; break;
nanosTimeout = deadline - System.nanoTime();
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
} }
if (acquireQueued(node, savedState) && interruptMode != THROW_IE) if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT; interruptMode = REINTERRUPT;
...@@ -2093,7 +2085,7 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2093,7 +2085,7 @@ public abstract class AbstractQueuedSynchronizer
unlinkCancelledWaiters(); unlinkCancelledWaiters();
if (interruptMode != 0) if (interruptMode != 0)
reportInterruptAfterWait(interruptMode); reportInterruptAfterWait(interruptMode);
return nanosTimeout - (System.nanoTime() - lastTime); return deadline - System.nanoTime();
} }
/** /**
...@@ -2101,9 +2093,8 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2101,9 +2093,8 @@ public abstract class AbstractQueuedSynchronizer
* <ol> * <ol>
* <li> If current thread is interrupted, throw InterruptedException. * <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled, interrupted, or timed out. * <li> Block until signalled, interrupted, or timed out.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -2113,8 +2104,6 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2113,8 +2104,6 @@ public abstract class AbstractQueuedSynchronizer
*/ */
public final boolean awaitUntil(Date deadline) public final boolean awaitUntil(Date deadline)
throws InterruptedException { throws InterruptedException {
if (deadline == null)
throw new NullPointerException();
long abstime = deadline.getTime(); long abstime = deadline.getTime();
if (Thread.interrupted()) if (Thread.interrupted())
throw new InterruptedException(); throw new InterruptedException();
...@@ -2145,9 +2134,8 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2145,9 +2134,8 @@ public abstract class AbstractQueuedSynchronizer
* <ol> * <ol>
* <li> If current thread is interrupted, throw InterruptedException. * <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}. * <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with * <li> Invoke {@link #release} with saved state as argument,
* saved state as argument, throwing * throwing IllegalMonitorStateException if it fails.
* IllegalMonitorStateException if it fails.
* <li> Block until signalled, interrupted, or timed out. * <li> Block until signalled, interrupted, or timed out.
* <li> Reacquire by invoking specialized version of * <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument. * {@link #acquire} with saved state as argument.
...@@ -2157,14 +2145,12 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2157,14 +2145,12 @@ public abstract class AbstractQueuedSynchronizer
*/ */
public final boolean await(long time, TimeUnit unit) public final boolean await(long time, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
if (unit == null)
throw new NullPointerException();
long nanosTimeout = unit.toNanos(time); long nanosTimeout = unit.toNanos(time);
if (Thread.interrupted()) if (Thread.interrupted())
throw new InterruptedException(); throw new InterruptedException();
Node node = addConditionWaiter(); Node node = addConditionWaiter();
int savedState = fullyRelease(node); int savedState = fullyRelease(node);
long lastTime = System.nanoTime(); final long deadline = System.nanoTime() + nanosTimeout;
boolean timedout = false; boolean timedout = false;
int interruptMode = 0; int interruptMode = 0;
while (!isOnSyncQueue(node)) { while (!isOnSyncQueue(node)) {
...@@ -2176,9 +2162,7 @@ public abstract class AbstractQueuedSynchronizer ...@@ -2176,9 +2162,7 @@ public abstract class AbstractQueuedSynchronizer
LockSupport.parkNanos(this, nanosTimeout); LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break; break;
long now = System.nanoTime(); nanosTimeout = deadline - System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
} }
if (acquireQueued(node, savedState) && interruptMode != THROW_IE) if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT; interruptMode = REINTERRUPT;
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
*/ */
package java.util.concurrent.locks; package java.util.concurrent.locks;
import java.util.concurrent.*; import java.util.concurrent.TimeUnit;
import java.util.Date; import java.util.Date;
/** /**
...@@ -360,10 +360,9 @@ public interface Condition { ...@@ -360,10 +360,9 @@ public interface Condition {
/** /**
* Causes the current thread to wait until it is signalled or interrupted, * Causes the current thread to wait until it is signalled or interrupted,
* or the specified waiting time elapses. This method is behaviorally * or the specified waiting time elapses. This method is behaviorally
* equivalent to:<br> * equivalent to:
* <pre> * <pre> {@code awaitNanos(unit.toNanos(time)) > 0}</pre>
* awaitNanos(unit.toNanos(time)) &gt; 0 *
* </pre>
* @param time the maximum time to wait * @param time the maximum time to wait
* @param unit the time unit of the {@code time} argument * @param unit the time unit of the {@code time} argument
* @return {@code false} if the waiting time detectably elapsed * @return {@code false} if the waiting time detectably elapsed
......
...@@ -77,14 +77,14 @@ import java.util.concurrent.TimeUnit; ...@@ -77,14 +77,14 @@ import java.util.concurrent.TimeUnit;
* methods and statements. In most cases, the following idiom * methods and statements. In most cases, the following idiom
* should be used: * should be used:
* *
* <pre><tt> Lock l = ...; * <pre> {@code
* Lock l = ...;
* l.lock(); * l.lock();
* try { * try {
* // access the resource protected by this lock * // access the resource protected by this lock
* } finally { * } finally {
* l.unlock(); * l.unlock();
* } * }}</pre>
* </tt></pre>
* *
* When locking and unlocking occur in different scopes, care must be * When locking and unlocking occur in different scopes, care must be
* taken to ensure that all code that is executed while the lock is * taken to ensure that all code that is executed while the lock is
...@@ -120,8 +120,9 @@ import java.util.concurrent.TimeUnit; ...@@ -120,8 +120,9 @@ import java.util.concurrent.TimeUnit;
* *
* <p>All {@code Lock} implementations <em>must</em> enforce the same * <p>All {@code Lock} implementations <em>must</em> enforce the same
* memory synchronization semantics as provided by the built-in monitor * memory synchronization semantics as provided by the built-in monitor
* lock, as described in section 17.4 of * lock, as described in
* <cite>The Java&trade; Language Specification</cite>: * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/index.html">
* The Java Language Specification, Third Edition (17.4 Memory Model)</a>:
* <ul> * <ul>
* <li>A successful {@code lock} operation has the same memory * <li>A successful {@code lock} operation has the same memory
* synchronization effects as a successful <em>Lock</em> action. * synchronization effects as a successful <em>Lock</em> action.
...@@ -239,7 +240,7 @@ public interface Lock { ...@@ -239,7 +240,7 @@ public interface Lock {
* immediately with the value {@code false}. * immediately with the value {@code false}.
* *
* <p>A typical usage idiom for this method would be: * <p>A typical usage idiom for this method would be:
* <pre> * <pre> {@code
* Lock lock = ...; * Lock lock = ...;
* if (lock.tryLock()) { * if (lock.tryLock()) {
* try { * try {
...@@ -249,8 +250,8 @@ public interface Lock { ...@@ -249,8 +250,8 @@ public interface Lock {
* } * }
* } else { * } else {
* // perform alternative actions * // perform alternative actions
* } * }}</pre>
* </pre> *
* This usage ensures that the lock is unlocked if it was acquired, and * This usage ensures that the lock is unlocked if it was acquired, and
* doesn't try to unlock if the lock was not acquired. * doesn't try to unlock if the lock was not acquired.
* *
......
...@@ -34,10 +34,8 @@ ...@@ -34,10 +34,8 @@
*/ */
package java.util.concurrent.locks; package java.util.concurrent.locks;
import java.util.concurrent.*;
import sun.misc.Unsafe; import sun.misc.Unsafe;
/** /**
* Basic thread blocking primitives for creating locks and other * Basic thread blocking primitives for creating locks and other
* synchronization classes. * synchronization classes.
...@@ -78,7 +76,10 @@ import sun.misc.Unsafe; ...@@ -78,7 +76,10 @@ import sun.misc.Unsafe;
* higher-level synchronization utilities, and are not in themselves * higher-level synchronization utilities, and are not in themselves
* useful for most concurrency control applications. The {@code park} * useful for most concurrency control applications. The {@code park}
* method is designed for use only in constructions of the form: * method is designed for use only in constructions of the form:
* <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre> *
* <pre> {@code
* while (!canProceed()) { ... LockSupport.park(this); }}</pre>
*
* where neither {@code canProceed} nor any other actions prior to the * where neither {@code canProceed} nor any other actions prior to the
* call to {@code park} entail locking or blocking. Because only one * call to {@code park} entail locking or blocking. Because only one
* permit is associated with each thread, any intermediary uses of * permit is associated with each thread, any intermediary uses of
...@@ -86,7 +87,7 @@ import sun.misc.Unsafe; ...@@ -86,7 +87,7 @@ import sun.misc.Unsafe;
* *
* <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
* non-reentrant lock class: * non-reentrant lock class:
* <pre>{@code * <pre> {@code
* class FIFOMutex { * class FIFOMutex {
* private final AtomicBoolean locked = new AtomicBoolean(false); * private final AtomicBoolean locked = new AtomicBoolean(false);
* private final Queue<Thread> waiters * private final Queue<Thread> waiters
...@@ -116,7 +117,6 @@ import sun.misc.Unsafe; ...@@ -116,7 +117,6 @@ import sun.misc.Unsafe;
* } * }
* }}</pre> * }}</pre>
*/ */
public class LockSupport { public class LockSupport {
private LockSupport() {} // Cannot be instantiated. private LockSupport() {} // Cannot be instantiated.
......
...@@ -34,9 +34,8 @@ ...@@ -34,9 +34,8 @@
*/ */
package java.util.concurrent.locks; package java.util.concurrent.locks;
import java.util.*; import java.util.concurrent.TimeUnit;
import java.util.concurrent.*; import java.util.Collection;
import java.util.concurrent.atomic.*;
/** /**
* A reentrant mutual exclusion {@link Lock} with the same basic * A reentrant mutual exclusion {@link Lock} with the same basic
...@@ -73,7 +72,7 @@ import java.util.concurrent.atomic.*; ...@@ -73,7 +72,7 @@ import java.util.concurrent.atomic.*;
* follow a call to {@code lock} with a {@code try} block, most * follow a call to {@code lock} with a {@code try} block, most
* typically in a before/after construction such as: * typically in a before/after construction such as:
* *
* <pre> * <pre> {@code
* class X { * class X {
* private final ReentrantLock lock = new ReentrantLock(); * private final ReentrantLock lock = new ReentrantLock();
* // ... * // ...
...@@ -86,8 +85,7 @@ import java.util.concurrent.atomic.*; ...@@ -86,8 +85,7 @@ import java.util.concurrent.atomic.*;
* lock.unlock() * lock.unlock()
* } * }
* } * }
* } * }}</pre>
* </pre>
* *
* <p>In addition to implementing the {@link Lock} interface, this * <p>In addition to implementing the {@link Lock} interface, this
* class defines methods {@code isLocked} and * class defines methods {@code isLocked} and
...@@ -187,8 +185,7 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -187,8 +185,7 @@ public class ReentrantLock implements Lock, java.io.Serializable {
} }
/** /**
* Reconstitutes this lock instance from a stream. * Reconstitutes the instance from a stream (that is, deserializes it).
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
...@@ -383,8 +380,11 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -383,8 +380,11 @@ public class ReentrantLock implements Lock, java.io.Serializable {
* method. If you want a timed {@code tryLock} that does permit barging on * method. If you want a timed {@code tryLock} that does permit barging on
* a fair lock then combine the timed and un-timed forms together: * a fair lock then combine the timed and un-timed forms together:
* *
* <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } * <pre> {@code
* </pre> * if (lock.tryLock() ||
* lock.tryLock(timeout, unit)) {
* ...
* }}</pre>
* *
* <p>If the current thread * <p>If the current thread
* already holds this lock then the hold count is incremented by one and * already holds this lock then the hold count is incremented by one and
...@@ -438,7 +438,6 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -438,7 +438,6 @@ public class ReentrantLock implements Lock, java.io.Serializable {
* the lock could be acquired * the lock could be acquired
* @throws InterruptedException if the current thread is interrupted * @throws InterruptedException if the current thread is interrupted
* @throws NullPointerException if the time unit is null * @throws NullPointerException if the time unit is null
*
*/ */
public boolean tryLock(long timeout, TimeUnit unit) public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
...@@ -514,7 +513,7 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -514,7 +513,7 @@ public class ReentrantLock implements Lock, java.io.Serializable {
* not be entered with the lock already held then we can assert that * not be entered with the lock already held then we can assert that
* fact: * fact:
* *
* <pre> * <pre> {@code
* class X { * class X {
* ReentrantLock lock = new ReentrantLock(); * ReentrantLock lock = new ReentrantLock();
* // ... * // ...
...@@ -527,8 +526,7 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -527,8 +526,7 @@ public class ReentrantLock implements Lock, java.io.Serializable {
* lock.unlock(); * lock.unlock();
* } * }
* } * }
* } * }}</pre>
* </pre>
* *
* @return the number of holds on this lock by the current thread, * @return the number of holds on this lock by the current thread,
* or zero if this lock is not held by the current thread * or zero if this lock is not held by the current thread
...@@ -545,7 +543,7 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -545,7 +543,7 @@ public class ReentrantLock implements Lock, java.io.Serializable {
* testing. For example, a method that should only be called while * testing. For example, a method that should only be called while
* a lock is held can assert that this is the case: * a lock is held can assert that this is the case:
* *
* <pre> * <pre> {@code
* class X { * class X {
* ReentrantLock lock = new ReentrantLock(); * ReentrantLock lock = new ReentrantLock();
* // ... * // ...
...@@ -554,13 +552,12 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -554,13 +552,12 @@ public class ReentrantLock implements Lock, java.io.Serializable {
* assert lock.isHeldByCurrentThread(); * assert lock.isHeldByCurrentThread();
* // ... method body * // ... method body
* } * }
* } * }}</pre>
* </pre>
* *
* <p>It can also be used to ensure that a reentrant lock is used * <p>It can also be used to ensure that a reentrant lock is used
* in a non-reentrant manner, for example: * in a non-reentrant manner, for example:
* *
* <pre> * <pre> {@code
* class X { * class X {
* ReentrantLock lock = new ReentrantLock(); * ReentrantLock lock = new ReentrantLock();
* // ... * // ...
...@@ -574,8 +571,7 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -574,8 +571,7 @@ public class ReentrantLock implements Lock, java.io.Serializable {
* lock.unlock(); * lock.unlock();
* } * }
* } * }
* } * }}</pre>
* </pre>
* *
* @return {@code true} if current thread holds this lock and * @return {@code true} if current thread holds this lock and
* {@code false} otherwise * {@code false} otherwise
...@@ -636,7 +632,6 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -636,7 +632,6 @@ public class ReentrantLock implements Lock, java.io.Serializable {
return sync.hasQueuedThreads(); return sync.hasQueuedThreads();
} }
/** /**
* Queries whether the given thread is waiting to acquire this * Queries whether the given thread is waiting to acquire this
* lock. Note that because cancellations may occur at any time, a * lock. Note that because cancellations may occur at any time, a
...@@ -652,7 +647,6 @@ public class ReentrantLock implements Lock, java.io.Serializable { ...@@ -652,7 +647,6 @@ public class ReentrantLock implements Lock, java.io.Serializable {
return sync.isQueued(thread); return sync.isQueued(thread);
} }
/** /**
* Returns an estimate of the number of threads waiting to * Returns an estimate of the number of threads waiting to
* acquire this lock. The value is only an estimate because the number of * acquire this lock. The value is only an estimate because the number of
......
...@@ -34,9 +34,8 @@ ...@@ -34,9 +34,8 @@
*/ */
package java.util.concurrent.locks; package java.util.concurrent.locks;
import java.util.concurrent.*; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.*; import java.util.Collection;
import java.util.*;
/** /**
* An implementation of {@link ReadWriteLock} supporting similar * An implementation of {@link ReadWriteLock} supporting similar
...@@ -62,7 +61,7 @@ import java.util.*; ...@@ -62,7 +61,7 @@ import java.util.*;
* <dt><b><i>Fair mode</i></b> * <dt><b><i>Fair mode</i></b>
* <dd> When constructed as fair, threads contend for entry using an * <dd> When constructed as fair, threads contend for entry using an
* approximately arrival-order policy. When the currently held lock * approximately arrival-order policy. When the currently held lock
* is released either the longest-waiting single writer thread will * is released, either the longest-waiting single writer thread will
* be assigned the write lock, or if there is a group of reader threads * be assigned the write lock, or if there is a group of reader threads
* waiting longer than all waiting writer threads, that group will be * waiting longer than all waiting writer threads, that group will be
* assigned the read lock. * assigned the read lock.
...@@ -80,8 +79,8 @@ import java.util.*; ...@@ -80,8 +79,8 @@ import java.util.*;
* will block unless both the read lock and write lock are free (which * will block unless both the read lock and write lock are free (which
* implies there are no waiting threads). (Note that the non-blocking * implies there are no waiting threads). (Note that the non-blocking
* {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
* do not honor this fair setting and will acquire the lock if it is * do not honor this fair setting and will immediately acquire the lock
* possible, regardless of waiting threads.) * if it is possible, regardless of waiting threads.)
* <p> * <p>
* </dl> * </dl>
* *
...@@ -176,7 +175,7 @@ import java.util.*; ...@@ -176,7 +175,7 @@ import java.util.*;
* is a class using a TreeMap that is expected to be large and * is a class using a TreeMap that is expected to be large and
* concurrently accessed. * concurrently accessed.
* *
* <pre>{@code * <pre> {@code
* class RWDictionary { * class RWDictionary {
* private final Map<String, Data> m = new TreeMap<String, Data>(); * private final Map<String, Data> m = new TreeMap<String, Data>();
* private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
...@@ -213,7 +212,6 @@ import java.util.*; ...@@ -213,7 +212,6 @@ import java.util.*;
* *
* @since 1.5 * @since 1.5
* @author Doug Lea * @author Doug Lea
*
*/ */
public class ReentrantReadWriteLock public class ReentrantReadWriteLock
implements ReadWriteLock, java.io.Serializable { implements ReadWriteLock, java.io.Serializable {
...@@ -654,8 +652,7 @@ public class ReentrantReadWriteLock ...@@ -654,8 +652,7 @@ public class ReentrantReadWriteLock
} }
/** /**
* Reconstitute this lock instance from a stream * Reconstitutes the instance from a stream (that is, deserializes it).
* @param s the stream
*/ */
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
...@@ -819,8 +816,11 @@ public class ReentrantReadWriteLock ...@@ -819,8 +816,11 @@ public class ReentrantReadWriteLock
* permit barging on a fair lock then combine the timed and * permit barging on a fair lock then combine the timed and
* un-timed forms together: * un-timed forms together:
* *
* <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } * <pre> {@code
* </pre> * if (lock.tryLock() ||
* lock.tryLock(timeout, unit)) {
* ...
* }}</pre>
* *
* <p>If the write lock is held by another thread then the * <p>If the write lock is held by another thread then the
* current thread becomes disabled for thread scheduling * current thread becomes disabled for thread scheduling
...@@ -866,7 +866,6 @@ public class ReentrantReadWriteLock ...@@ -866,7 +866,6 @@ public class ReentrantReadWriteLock
* @return {@code true} if the read lock was acquired * @return {@code true} if the read lock was acquired
* @throws InterruptedException if the current thread is interrupted * @throws InterruptedException if the current thread is interrupted
* @throws NullPointerException if the time unit is null * @throws NullPointerException if the time unit is null
*
*/ */
public boolean tryLock(long timeout, TimeUnit unit) public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
...@@ -1049,8 +1048,11 @@ public class ReentrantReadWriteLock ...@@ -1049,8 +1048,11 @@ public class ReentrantReadWriteLock
* that does permit barging on a fair lock then combine the * that does permit barging on a fair lock then combine the
* timed and un-timed forms together: * timed and un-timed forms together:
* *
* <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } * <pre> {@code
* </pre> * if (lock.tryLock() ||
* lock.tryLock(timeout, unit)) {
* ...
* }}</pre>
* *
* <p>If the current thread already holds this lock then the * <p>If the current thread already holds this lock then the
* hold count is incremented by one and the method returns * hold count is incremented by one and the method returns
...@@ -1108,7 +1110,6 @@ public class ReentrantReadWriteLock ...@@ -1108,7 +1110,6 @@ public class ReentrantReadWriteLock
* *
* @throws InterruptedException if the current thread is interrupted * @throws InterruptedException if the current thread is interrupted
* @throws NullPointerException if the time unit is null * @throws NullPointerException if the time unit is null
*
*/ */
public boolean tryLock(long timeout, TimeUnit unit) public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
......
...@@ -188,7 +188,7 @@ ...@@ -188,7 +188,7 @@
* A {@code CopyOnWriteArrayList} is preferable to a synchronized * A {@code CopyOnWriteArrayList} is preferable to a synchronized
* {@code ArrayList} when the expected number of reads and traversals * {@code ArrayList} when the expected number of reads and traversals
* greatly outnumber the number of updates to a list. * greatly outnumber the number of updates to a list.
*
* <p>The "Concurrent" prefix used with some classes in this package * <p>The "Concurrent" prefix used with some classes in this package
* is a shorthand indicating several differences from similar * is a shorthand indicating several differences from similar
* "synchronized" classes. For example {@code java.util.Hashtable} and * "synchronized" classes. For example {@code java.util.Hashtable} and
...@@ -218,9 +218,8 @@ ...@@ -218,9 +218,8 @@
* *
* <h2><a name="MemoryVisibility">Memory Consistency Properties</a></h2> * <h2><a name="MemoryVisibility">Memory Consistency Properties</a></h2>
* *
* Chapter 17 of * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/index.html">
* <cite>The Java&trade; Language Specification</cite> * Chapter 17 of the Java Language Specification</a> defines the
* defines the
* <i>happens-before</i> relation on memory operations such as reads and * <i>happens-before</i> relation on memory operations such as reads and
* writes of shared variables. The results of a write by one thread are * writes of shared variables. The results of a write by one thread are
* guaranteed to be visible to a read by another thread only if the write * guaranteed to be visible to a read by another thread only if the write
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册