A JSR-166 expert group code review found a number of inconsistencies
and added some clarifications.
The mutating methods of ConcurrentMap should be documented as being optional -
that is, they might throw UnsupportedOperationException.
On the other hand, the concrete ConcurrentHashMap implementation should *not*
be documented to throw UnsupportedOperationException.
Semaphore class' interaction between fairness and acquire() should be
clarified.
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/BlockingQueue.java 2004-06-14 12:05:48.239032000 -0700
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/BlockingQueue.java 2004-06-24 22:53:32.065800000 -0700
@@ -174,8 +174,8 @@
* <p>Note that you <em>cannot</em> always tell if
* an attempt to <tt>add</tt> an element will succeed by
* inspecting <tt>remainingCapacity</tt> because it may be the
- * case that a waiting consumer is ready to <tt>take</tt> an
- * element out of an otherwise full queue.
+ * case that another thread is about to <tt>put</tt> or <tt>take</tt> an
+ * element.
* @return the remaining capacity
*/
int remainingCapacity();
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/ConcurrentHashMap.java 2004-06-14 12:05:48.536884000 -0700
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/ConcurrentHashMap.java 2004-06-24 22:56:39.831152000 -0700
@@ -626,7 +626,8 @@
/**
* Creates a new map with the same mappings as the given map. The
* map is created with a capacity of twice the number of mappings in
- * the given map or 11 (whichever is greater), and a default load factor.
+ * the given map or 11 (whichever is greater), and a default load factor
+ * and concurrencyLevel.
* @param t the map
*/
public ConcurrentHashMap(Map<? extends K, ? extends V> t) {
@@ -864,8 +865,6 @@
* with the specified key, if the implementation supports
* <tt>null</tt> values.
*
- * @throws UnsupportedOperationException if the <tt>put</tt> operation is
- * not supported by this map.
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map.
* @throws NullPointerException if the specified key or value is
@@ -996,7 +995,7 @@
* <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
* <tt>clear</tt> operations. It does not support the <tt>add</tt> or
* <tt>addAll</tt> operations.
- * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
@@ -1018,7 +1017,7 @@
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
- * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
@@ -1041,7 +1040,7 @@
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
- * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/ConcurrentMap.java 2004-02-09 21:56:04.604949000 -0800
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/ConcurrentMap.java 2004-06-24 23:00:00.473344000 -0700
@@ -67,6 +67,8 @@
* @param key key with which the specified value is associated.
* @param value value associated with the specified key.
* @return true if the value was removed, false otherwise
+ * @throws UnsupportedOperationException if the <tt>remove</tt> operation is
+ * not supported by this map.
* @throws NullPointerException if this map does not permit <tt>null</tt>
* keys or values, and the specified key or value is
* <tt>null</tt>.
@@ -88,6 +90,8 @@
* @param oldValue value expected to be associated with the specified key.
* @param newValue value to be associated with the specified key.
* @return true if the value was replaced
+ * @throws UnsupportedOperationException if the <tt>put</tt> operation is
+ * not supported by this map.
* @throws NullPointerException if this map does not permit <tt>null</tt>
* keys or values, and the specified key or value is
* <tt>null</tt>.
@@ -110,6 +114,8 @@
* also indicate that the map previously associated <tt>null</tt>
* with the specified key, if the implementation supports
* <tt>null</tt> values.
+ * @throws UnsupportedOperationException if the <tt>put</tt> operation is
+ * not supported by this map.
* @throws NullPointerException if this map does not permit <tt>null</tt>
* keys or values, and the specified key or value is
* <tt>null</tt>.
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/CyclicBarrier.java 2004-02-09 21:56:05.409115000 -0800
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/CyclicBarrier.java 2004-06-24 23:01:10.170279000 -0700
@@ -329,6 +329,10 @@
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
+ * <p>If the specified waiting time elapses then {@link TimeoutException}
+ * is thrown. If the time is less than or equal to zero, the
+ * method will not wait at all.
+ *
* <p>If the barrier is {@link #reset} while any thread is waiting, or if
* the barrier {@link #isBroken is broken} when <tt>await</tt> is invoked,
* or while any thread is waiting,
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/Semaphore.java 2004-02-27 22:51:10.698434000 -0800
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/Semaphore.java 2004-06-24 23:14:07.230989000 -0700
@@ -94,15 +94,19 @@
* guarantees about the order in which threads acquire permits. In
* particular, <em>barging</em> is permitted, that is, a thread
* invoking {@link #acquire} can be allocated a permit ahead of a
- * thread that has been waiting. When fairness is set true, the
+ * thread that has been waiting - logically the new thread places itself at
+ * the head of the queue of waiting threads. When fairness is set true, the
* semaphore guarantees that threads invoking any of the {@link
- * #acquire() acquire} methods are allocated permits in the order in
+ * #acquire() acquire} methods are selected to obtain permits in the order in
* which their invocation of those methods was processed
* (first-in-first-out; FIFO). Note that FIFO ordering necessarily
* applies to specific internal points of execution within these
* methods. So, it is possible for one thread to invoke
* <tt>acquire</tt> before another, but reach the ordering point after
* the other, and similarly upon return from the method.
+ * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
+ * honor the fairness setting, but will take any permits that are
+ * available.
*
* <p>Generally, semaphores used to control resource access should be
* initialized as fair, to ensure that no thread is starved out from
@@ -368,9 +372,9 @@
* Releases a permit, returning it to the semaphore.
* <p>Releases a permit, increasing the number of available permits
* by one.
- * If any threads are blocking trying to acquire a permit, then one
+ * If any threads are trying to acquire a permit, then one
* is selected and given the permit that was just released.
- * That thread is re-enabled for thread scheduling purposes.
+ * That thread is (re)enabled for thread scheduling purposes.
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling {@link #acquire}.
* Correct usage of a semaphore is established by programming convention
@@ -409,8 +413,8 @@
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
* Any permits that were to be assigned to this thread are instead
- * assigned to the next waiting thread(s), as if
- * they had been made available by a call to {@link #release()}.
+ * assigned to other threads trying to acquire permits, as if
+ * permits had been made available by a call to {@link #release()}.
*
* @param permits the number of permits to acquire
*
@@ -514,16 +518,16 @@
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
* Any permits that were to be assigned to this thread, are instead
- * assigned to the next waiting thread(s), as if
- * they had been made available by a call to {@link #release()}.
+ * assigned to other threads trying to acquire permits, as if
+ * the permits had been made available by a call to {@link #release()}.
*
* <p>If the specified waiting time elapses then the value <tt>false</tt>
* is returned.
* If the time is
* less than or equal to zero, the method will not wait at all.
* Any permits that were to be assigned to this thread, are instead
- * assigned to the next waiting thread(s), as if
- * they had been made available by a call to {@link #release()}.
+ * assigned to other threads trying to acquire permits, as if
+ * the permits had been made available by a call to {@link #release()}.
*
* @param permits the number of permits to acquire
* @param timeout the maximum time to wait for the permits
@@ -547,17 +551,14 @@
* Releases the given number of permits, returning them to the semaphore.
* <p>Releases the given number of permits, increasing the number of
* available permits by that amount.
- * If any threads are blocking trying to acquire permits, then the
- * one that has been waiting the longest
+ * If any threads are trying to acquire permits, then one
* is selected and given the permits that were just released.
* If the number of available permits satisfies that thread's request
- * then that thread is re-enabled for thread scheduling purposes; otherwise
- * the thread continues to wait. If there are still permits available
- * after the first thread's request has been satisfied, then those permits
- * are assigned to the next waiting thread. If it is satisfied then it is
- * re-enabled for thread scheduling purposes. This continues until there
- * are insufficient permits to satisfy the next waiting thread, or there
- * are no more waiting threads.
+ * then that thread is (re)enabled for thread scheduling purposes;
+ * otherwise the thread will wait until sufficient permits are available.
+ * If there are still permits available
+ * after this thread's request has been satisfied, then those permits
+ * are assigned in turn to other threads trying to acquire permits.
*
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling {@link Semaphore#acquire acquire}.
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/locks/ReentrantLock.java 2004-02-09 21:56:12.307012000 -0800
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/locks/ReentrantLock.java 2004-06-24 22:42:21.443254000 -0700
@@ -37,6 +37,9 @@
* fair lock may obtain it multiple times in succession while other
* active threads are not progressing and not currently holding the
* lock.
+ * Also note that the untimed {@link #tryLock() tryLock} method does not
+ * honor the fairness setting. It will succeed if the lock
+ * is available even if other threads are waiting.
*
* <p> It is recommended practice to <em>always</em> immediately
* follow a call to <tt>lock</tt> with a <tt>try</tt> block, most
and added some clarifications.
The mutating methods of ConcurrentMap should be documented as being optional -
that is, they might throw UnsupportedOperationException.
On the other hand, the concrete ConcurrentHashMap implementation should *not*
be documented to throw UnsupportedOperationException.
Semaphore class' interaction between fairness and acquire() should be
clarified.
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/BlockingQueue.java 2004-06-14 12:05:48.239032000 -0700
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/BlockingQueue.java 2004-06-24 22:53:32.065800000 -0700
@@ -174,8 +174,8 @@
* <p>Note that you <em>cannot</em> always tell if
* an attempt to <tt>add</tt> an element will succeed by
* inspecting <tt>remainingCapacity</tt> because it may be the
- * case that a waiting consumer is ready to <tt>take</tt> an
- * element out of an otherwise full queue.
+ * case that another thread is about to <tt>put</tt> or <tt>take</tt> an
+ * element.
* @return the remaining capacity
*/
int remainingCapacity();
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/ConcurrentHashMap.java 2004-06-14 12:05:48.536884000 -0700
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/ConcurrentHashMap.java 2004-06-24 22:56:39.831152000 -0700
@@ -626,7 +626,8 @@
/**
* Creates a new map with the same mappings as the given map. The
* map is created with a capacity of twice the number of mappings in
- * the given map or 11 (whichever is greater), and a default load factor.
+ * the given map or 11 (whichever is greater), and a default load factor
+ * and concurrencyLevel.
* @param t the map
*/
public ConcurrentHashMap(Map<? extends K, ? extends V> t) {
@@ -864,8 +865,6 @@
* with the specified key, if the implementation supports
* <tt>null</tt> values.
*
- * @throws UnsupportedOperationException if the <tt>put</tt> operation is
- * not supported by this map.
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map.
* @throws NullPointerException if the specified key or value is
@@ -996,7 +995,7 @@
* <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
* <tt>clear</tt> operations. It does not support the <tt>add</tt> or
* <tt>addAll</tt> operations.
- * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
@@ -1018,7 +1017,7 @@
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
- * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
@@ -1041,7 +1040,7 @@
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
- * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/ConcurrentMap.java 2004-02-09 21:56:04.604949000 -0800
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/ConcurrentMap.java 2004-06-24 23:00:00.473344000 -0700
@@ -67,6 +67,8 @@
* @param key key with which the specified value is associated.
* @param value value associated with the specified key.
* @return true if the value was removed, false otherwise
+ * @throws UnsupportedOperationException if the <tt>remove</tt> operation is
+ * not supported by this map.
* @throws NullPointerException if this map does not permit <tt>null</tt>
* keys or values, and the specified key or value is
* <tt>null</tt>.
@@ -88,6 +90,8 @@
* @param oldValue value expected to be associated with the specified key.
* @param newValue value to be associated with the specified key.
* @return true if the value was replaced
+ * @throws UnsupportedOperationException if the <tt>put</tt> operation is
+ * not supported by this map.
* @throws NullPointerException if this map does not permit <tt>null</tt>
* keys or values, and the specified key or value is
* <tt>null</tt>.
@@ -110,6 +114,8 @@
* also indicate that the map previously associated <tt>null</tt>
* with the specified key, if the implementation supports
* <tt>null</tt> values.
+ * @throws UnsupportedOperationException if the <tt>put</tt> operation is
+ * not supported by this map.
* @throws NullPointerException if this map does not permit <tt>null</tt>
* keys or values, and the specified key or value is
* <tt>null</tt>.
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/CyclicBarrier.java 2004-02-09 21:56:05.409115000 -0800
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/CyclicBarrier.java 2004-06-24 23:01:10.170279000 -0700
@@ -329,6 +329,10 @@
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
+ * <p>If the specified waiting time elapses then {@link TimeoutException}
+ * is thrown. If the time is less than or equal to zero, the
+ * method will not wait at all.
+ *
* <p>If the barrier is {@link #reset} while any thread is waiting, or if
* the barrier {@link #isBroken is broken} when <tt>await</tt> is invoked,
* or while any thread is waiting,
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/Semaphore.java 2004-02-27 22:51:10.698434000 -0800
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/Semaphore.java 2004-06-24 23:14:07.230989000 -0700
@@ -94,15 +94,19 @@
* guarantees about the order in which threads acquire permits. In
* particular, <em>barging</em> is permitted, that is, a thread
* invoking {@link #acquire} can be allocated a permit ahead of a
- * thread that has been waiting. When fairness is set true, the
+ * thread that has been waiting - logically the new thread places itself at
+ * the head of the queue of waiting threads. When fairness is set true, the
* semaphore guarantees that threads invoking any of the {@link
- * #acquire() acquire} methods are allocated permits in the order in
+ * #acquire() acquire} methods are selected to obtain permits in the order in
* which their invocation of those methods was processed
* (first-in-first-out; FIFO). Note that FIFO ordering necessarily
* applies to specific internal points of execution within these
* methods. So, it is possible for one thread to invoke
* <tt>acquire</tt> before another, but reach the ordering point after
* the other, and similarly upon return from the method.
+ * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
+ * honor the fairness setting, but will take any permits that are
+ * available.
*
* <p>Generally, semaphores used to control resource access should be
* initialized as fair, to ensure that no thread is starved out from
@@ -368,9 +372,9 @@
* Releases a permit, returning it to the semaphore.
* <p>Releases a permit, increasing the number of available permits
* by one.
- * If any threads are blocking trying to acquire a permit, then one
+ * If any threads are trying to acquire a permit, then one
* is selected and given the permit that was just released.
- * That thread is re-enabled for thread scheduling purposes.
+ * That thread is (re)enabled for thread scheduling purposes.
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling {@link #acquire}.
* Correct usage of a semaphore is established by programming convention
@@ -409,8 +413,8 @@
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
* Any permits that were to be assigned to this thread are instead
- * assigned to the next waiting thread(s), as if
- * they had been made available by a call to {@link #release()}.
+ * assigned to other threads trying to acquire permits, as if
+ * permits had been made available by a call to {@link #release()}.
*
* @param permits the number of permits to acquire
*
@@ -514,16 +518,16 @@
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
* Any permits that were to be assigned to this thread, are instead
- * assigned to the next waiting thread(s), as if
- * they had been made available by a call to {@link #release()}.
+ * assigned to other threads trying to acquire permits, as if
+ * the permits had been made available by a call to {@link #release()}.
*
* <p>If the specified waiting time elapses then the value <tt>false</tt>
* is returned.
* If the time is
* less than or equal to zero, the method will not wait at all.
* Any permits that were to be assigned to this thread, are instead
- * assigned to the next waiting thread(s), as if
- * they had been made available by a call to {@link #release()}.
+ * assigned to other threads trying to acquire permits, as if
+ * the permits had been made available by a call to {@link #release()}.
*
* @param permits the number of permits to acquire
* @param timeout the maximum time to wait for the permits
@@ -547,17 +551,14 @@
* Releases the given number of permits, returning them to the semaphore.
* <p>Releases the given number of permits, increasing the number of
* available permits by that amount.
- * If any threads are blocking trying to acquire permits, then the
- * one that has been waiting the longest
+ * If any threads are trying to acquire permits, then one
* is selected and given the permits that were just released.
* If the number of available permits satisfies that thread's request
- * then that thread is re-enabled for thread scheduling purposes; otherwise
- * the thread continues to wait. If there are still permits available
- * after the first thread's request has been satisfied, then those permits
- * are assigned to the next waiting thread. If it is satisfied then it is
- * re-enabled for thread scheduling purposes. This continues until there
- * are insufficient permits to satisfy the next waiting thread, or there
- * are no more waiting threads.
+ * then that thread is (re)enabled for thread scheduling purposes;
+ * otherwise the thread will wait until sufficient permits are available.
+ * If there are still permits available
+ * after this thread's request has been satisfied, then those permits
+ * are assigned in turn to other threads trying to acquire permits.
*
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling {@link Semaphore#acquire acquire}.
--- /u/martin/ws/tiger/src/share/classes/java/util/concurrent/locks/ReentrantLock.java 2004-02-09 21:56:12.307012000 -0800
+++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/locks/ReentrantLock.java 2004-06-24 22:42:21.443254000 -0700
@@ -37,6 +37,9 @@
* fair lock may obtain it multiple times in succession while other
* active threads are not progressing and not currently holding the
* lock.
+ * Also note that the untimed {@link #tryLock() tryLock} method does not
+ * honor the fairness setting. It will succeed if the lock
+ * is available even if other threads are waiting.
*
* <p> It is recommended practice to <em>always</em> immediately
* follow a call to <tt>lock</tt> with a <tt>try</tt> block, most