diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 649eaa563c7..0b0db4e8120 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -35,7 +35,9 @@ package java.util.concurrent; -import java.lang.reflect.Field; +import jdk.internal.misc.Unsafe; + +import java.lang.invoke.VarHandle; import java.util.AbstractSet; import java.util.Collection; import java.util.Collections; @@ -176,6 +178,8 @@ public class ConcurrentSkipListSet ConcurrentSkipListSet clone = (ConcurrentSkipListSet) super.clone(); clone.setMap(new ConcurrentSkipListMap(m)); + // Needed to ensure safe publication of setMap() + VarHandle.releaseFence(); return clone; } catch (CloneNotSupportedException e) { throw new InternalError(); @@ -527,12 +531,11 @@ public class ConcurrentSkipListSet /** Initializes map field; for use in clone. */ private void setMap(ConcurrentNavigableMap map) { - try { - Field mapField = ConcurrentSkipListSet.class.getDeclaredField("m"); - mapField.setAccessible(true); - mapField.set(this, map); - } catch (IllegalAccessException | NoSuchFieldException e) { - throw new Error(e); - } + final Unsafe U = Unsafe.getUnsafe(); + U.putReference( + this, + U.objectFieldOffset(ConcurrentSkipListSet.class, "m"), + map + ); } } diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java index 2d3bdb429e9..9024fca8024 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -35,7 +35,6 @@ package java.util.concurrent; import java.lang.invoke.VarHandle; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -57,6 +56,7 @@ import java.util.function.UnaryOperator; import java.util.stream.Stream; import java.util.stream.StreamSupport; import jdk.internal.access.SharedSecrets; +import jdk.internal.misc.Unsafe; import jdk.internal.util.ArraysSupport; /** @@ -2095,12 +2095,11 @@ public class CopyOnWriteArrayList /** Initializes the lock; for use when deserializing or cloning. */ private void resetLock() { - try { - Field lockField = CopyOnWriteArrayList.class.getDeclaredField("lock"); - lockField.setAccessible(true); - lockField.set(this, new Object()); - } catch (IllegalAccessException | NoSuchFieldException e) { - throw new Error(e); - } + final Unsafe U = Unsafe.getUnsafe(); + U.putReference( + this, + U.objectFieldOffset(CopyOnWriteArrayList.class, "lock"), + new Object() + ); } } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java index ff4e9fa7355..67315296a8d 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -35,10 +35,11 @@ package java.util.concurrent.atomic; +import jdk.internal.misc.Unsafe; + import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.lang.reflect.Array; -import java.lang.reflect.Field; import java.util.Arrays; import java.util.function.BinaryOperator; import java.util.function.UnaryOperator; @@ -330,14 +331,13 @@ public class AtomicReferenceArray implements java.io.Serializable { throw new java.io.InvalidObjectException("Not array type"); if (a.getClass() != Object[].class) a = Arrays.copyOf((Object[])a, Array.getLength(a), Object[].class); - try { - Field arrayField = AtomicReferenceArray.class.getDeclaredField("array"); - arrayField.setAccessible(true); - arrayField.set(this, a); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new Error(e); - } + final Unsafe U = Unsafe.getUnsafe(); + U.putReference( + this, + U.objectFieldOffset(AtomicReferenceArray.class, "array"), + a + ); } // jdk9 @@ -523,5 +523,4 @@ public class AtomicReferenceArray implements java.io.Serializable { public final boolean weakCompareAndSetRelease(int i, E expectedValue, E newValue) { return AA.weakCompareAndSetRelease(array, i, expectedValue, newValue); } - }