我创建了一个程序来检查是否@sun.misc.Contended
生效。这个想法是,当@Contended
生效时,注释类中的字段偏移量会更大。
如果我指定了-XX:-RestrictContended
标志,我可以看到 OpenJDK 上偏移量的预期差异。我在 OpenJ9 11 (jdk-11.0.1+13, Eclipse OpenJ9 VM-11.0.1) 上没有看到任何区别。
OpenJDK 输出是
readOnly: 12
writeOnly: 16
----
readOnly: 12
writeOnly: 144
OpenJ9 的输出是
readOnly: 8
writeOnly: 12
----
readOnly: 8
writeOnly: 12
该程序是
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Main {
public static class Baseline {
int readOnly;
int writeOnly;
}
public static class Contended {
int readOnly;
@sun.misc.Contended
int writeOnly;
}
public static void main(String[] args) throws Exception {
Baseline b = new Baseline();
Contended s = new Contended();
printOffsets(b);
System.out.println("----");
printOffsets(s);
}
// https://blog.hazelcast.com/using-sun-misc-unsafe-in-java-9/
@SuppressWarnings("restriction")
private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
singleoneInstanceField.setAccessible(true);
return (Unsafe) singleoneInstanceField.get(null);
}
// http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
public static void printOffsets(Object o) throws Exception {
Unsafe u = getUnsafe();
Class c = o.getClass();
for (Field f : c.getDeclaredFields()) {
if ((f.getModifiers() & Modifier.STATIC) == 0) {
printOffset(u, f);
}
}
}
public static void printOffset(Unsafe u, Field f) {
long offset = u.objectFieldOffset(f);
System.out.println(f.getName() + ": " + offset);
}
}