United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6275329 Add lazySet methods to atomic classes
JDK-6275329 : Add lazySet methods to atomic classes

Details
Type:
Enhancement
Submit Date:
2005-05-24
Status:
Resolved
Updated Date:
2010-04-02
Project Name:
JDK
Resolved Date:
2005-06-25
Component:
core-libs
OS:
generic
Sub-Component:
java.util.concurrent
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Relates:

Sub Tasks

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
EVALUATION

Will be integrated as part of the jsr166x project
###@###.### 2005-05-24 17:04:20 GMT
                                     
2005-05-24
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
                                     
2005-05-24



Hardware and Software, Engineered to Work Together