8355369: Remove setAccessible usage for setting final fields in java.util.concurrent

Reviewed-by: pminborg, dl, rgiulietti, alanb
This commit is contained in:
Viktor Klang 2025-04-24 14:14:24 +00:00
parent cf96b107d5
commit 356c4d9ca9
3 changed files with 26 additions and 25 deletions

View File

@ -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<E>
ConcurrentSkipListSet<E> clone =
(ConcurrentSkipListSet<E>) super.clone();
clone.setMap(new ConcurrentSkipListMap<E,Object>(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<E>
/** Initializes map field; for use in clone. */
private void setMap(ConcurrentNavigableMap<E,Object> 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
);
}
}

View File

@ -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<E>
/** 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()
);
}
}

View File

@ -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<E> 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<E> implements java.io.Serializable {
public final boolean weakCompareAndSetRelease(int i, E expectedValue, E newValue) {
return AA.weakCompareAndSetRelease(array, i, expectedValue, newValue);
}
}