JDK-6275329 : Add lazySet methods to atomic classes
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-05-24
  • Updated: 2017-05-16
  • Resolved: 2005-06-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b43Fixed
Related Reports
Relates :  
Description
Doug Lea writes

"As probably the last little JSR166 follow-up for Mustang,
we added a "lazySet" method to the Atomic classes
(AtomicInteger, AtomicReference, etc). This is a niche
method that is sometimes useful when fine-tuning code using
non-blocking data structures. The semantics are
that the write is guaranteed not to be re-ordered with any
previous write, but may be reordered with subsequent operations
(or equivalently, might not be visible to other threads) until
some other volatile write or synchronizing action occurs).

The main use case is for nulling out fields of nodes in
non-blocking data structures solely for the sake of avoiding
long-term garbage retention; it applies when it is harmless
if other threads see non-null values for a while, but you'd
like to ensure that structures are eventually GCable. In such
cases, you can get better performance by avoiding
the costs of the null volatile-write. There are a few
other use cases along these lines for non-reference-based
atomics as well, so the method is supported across all of the
AtomicX classes.

For people who like to think of these operations in terms of
machine-level barriers on common multiprocessors, lazySet
provides a preceeding store-store barrier (which is either
a no-op or very cheap on current platforms), but no
store-load barrier (which is usually the expensive part
of a volatile-write)."
###@###.### 2005-05-24 17:04:20 GMT

Comments
SUGGESTED FIX (In reverse diff form) --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicLong.java 2005-05-24 10:19:07.305990000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicLong.java 2005-04-18 11:52:03.999191000 -0700 @@ -85,16 +85,6 @@ } /** - * Eventually sets to the given value. - * - * @param newValue the new value - */ - public final void lazySet(long newValue) { - unsafe.putLongVolatile(this, valueOffset, newValue); - } - - - /** * Atomically sets to the given value and returns the old value. * * @param newValue the new value --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicLongFieldUpdater.java 2005-05-24 10:19:07.370932000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java 2005-05-16 20:39:42.235350000 -0700 @@ -99,15 +99,6 @@ public abstract void set(T obj, long newValue); /** - * Eventually sets the field of the given object managed by this - * updater to the given updated value. - * - * @param obj An object whose field to set - * @param newValue the new value - */ - public abstract void lazySet(T obj, long newValue); - - /** * Gets the current value held in the field of the given object managed * by this updater. * @@ -275,12 +266,6 @@ unsafe.putLongVolatile(obj, offset, newValue); } - public void lazySet(T obj, long newValue) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - unsafe.putLongVolatile(obj, offset, newValue); - } - public long get(T obj) { if (!tclass.isInstance(obj)) throw new ClassCastException(); @@ -337,14 +322,6 @@ } } - public void lazySet(T obj, long newValue) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - synchronized(this) { - unsafe.putLong(obj, offset, newValue); - } - } - public long get(T obj) { if (!tclass.isInstance(obj)) throw new ClassCastException(); --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicBoolean.java 2005-05-24 10:19:07.127839000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java 2005-04-18 11:51:59.179474000 -0700 @@ -98,15 +98,6 @@ } /** - * Eventually sets to the given value. - * - * @param newValue the new value - */ - public final void lazySet(boolean newValue) { - unsafe.putBoolean(this, valueOffset, newValue); - } - - /** * Atomically sets to the given value and returns the previous value. * * @param newValue the new value --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicInteger.java 2005-05-24 10:19:07.157972000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java 2005-04-18 11:52:00.522748000 -0700 @@ -71,15 +71,6 @@ } /** - * Eventually sets to the given value. - * - * @param newValue the new value - */ - public final void lazySet(int newValue) { - unsafe.putInt(this, valueOffset, newValue); - } - - /** * Atomically sets to the given value and returns the old value. * * @param newValue the new value --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicIntegerArray.java 2005-05-24 10:19:07.182189000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java 2005-04-18 11:52:01.673856000 -0700 @@ -95,16 +95,6 @@ } /** - * Eventually sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - */ - public final void lazySet(int i, int newValue) { - unsafe.putInt(array, rawIndex(i), newValue); - } - - /** * Atomically sets the element at position <tt>i</tt> to the given * value and returns the old value. * --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java 2005-05-24 10:19:07.232131000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java 2005-05-16 20:39:41.525673000 -0700 @@ -96,16 +96,6 @@ public abstract void set(T obj, int newValue); /** - * Eventually sets the field of the given object managed by this - * updater to the given updated value. - * - * @param obj An object whose field to set - * @param newValue the new value - */ - public abstract void lazySet(T obj, int newValue); - - - /** * Gets the current value held in the field of the given object managed * by this updater. * @@ -276,12 +266,6 @@ unsafe.putIntVolatile(obj, offset, newValue); } - public void lazySet(T obj, int newValue) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - unsafe.putInt(obj, offset, newValue); - } - public final int get(T obj) { if (!tclass.isInstance(obj)) throw new ClassCastException(); ==> diff -u -I '%[A-Z]%' -I '@(#)' -I '^[ */]*$' -I @version -I @test -w /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicLongArray.java /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicLongArray.java 2005-05-24 10:19:07.334461000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java 2005-04-18 11:52:05.198997000 -0700 @@ -94,17 +94,6 @@ } /** - * Eventually sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - */ - public final void lazySet(int i, long newValue) { - unsafe.putLongVolatile(array, rawIndex(i), newValue); - } - - - /** * Atomically sets the element at position <tt>i</tt> to the given value * and returns the old value. * --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java 2005-05-24 10:19:07.469122000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java 2005-05-16 20:39:42.890020000 -0700 @@ -114,15 +114,6 @@ public abstract void set(T obj, V newValue); /** - * Eventually sets the field of the given object managed by this - * updater to the given updated value. - * - * @param obj An object whose field to set - * @param newValue the new value - */ - public abstract void lazySet(T obj, V newValue); - - /** * Gets the current value held in the field of the given object managed * by this updater. * @@ -204,13 +195,6 @@ unsafe.putObjectVolatile(obj, offset, newValue); } - public void lazySet(T obj, V newValue) { - if (!tclass.isInstance(obj) || - (newValue != null && !vclass.isInstance(newValue))) - throw new ClassCastException(); - unsafe.putObject(obj, offset, newValue); - } - public V get(T obj) { if (!tclass.isInstance(obj)) throw new ClassCastException(); --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicReference.java 2005-05-24 10:19:07.407101000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicReference.java 2005-04-18 11:52:07.691639000 -0700 @@ -65,15 +65,6 @@ } /** - * Eventually sets to the given value. - * - * @param newValue the new value - */ - public final void lazySet(V newValue) { - unsafe.putObject(this, valueOffset, newValue); - } - - /** * Atomically sets the value to the given updated value * if the current value <tt>==</tt> the expected value. * @param expect the expected value --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/AtomicReferenceArray.java 2005-05-24 10:19:07.437378000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java 2005-04-18 11:52:08.933425000 -0700 @@ -95,17 +95,6 @@ } /** - * Eventually sets the element at position <tt>i</tt> to the given value. - * - * @param i the index - * @param newValue the new value - */ - public final void lazySet(int i, E newValue) { - unsafe.putObject(array, rawIndex(i), newValue); - } - - - /** * Atomically sets the element at position <tt>i</tt> to the given * value and returns the old value. * --- /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/atomic/package.html 2005-05-24 10:19:07.504495000 -0700 +++ /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/atomic/package.html 2004-02-27 20:16:33.893355000 -0800 @@ -71,14 +71,6 @@ <li> <tt>set</tt> has the memory effects of writing (assigning) a <tt>volatile</tt> variable. - <li> <tt>lazySet</tt> has the memory effects of writing (assigning) - a <tt>volatile</tt> variable except that it permits reorderings with - subsequent (but not previous) memory actions that do not themselves - impose reordering constraints with ordinary non-<tt>volatile</tt> - writes. Among other usage contexts, <tt>lazySet</tt> may apply when - nulling out, for the sake of garbage collection, a reference that is - never accessed again. - <li><tt>weakCompareAndSet</tt> atomically reads and conditionally writes a variable, is ordered with respect to other memory operations on that variable, but otherwise acts as an ###@###.### 2005-05-24 17:27:52 GMT
24-05-2005

EVALUATION Will be integrated as part of the jsr166x project ###@###.### 2005-05-24 17:04:20 GMT
24-05-2005