????????
????sun.misc.Unsafe?????2004??Java1.4?????????Java???????Java9?У???????JVM?????????Unsafe???????????????????????????????????????????????????????Unsafe?????????????????в?????????????????????????????????????Unsafe??
???????ЩJava??????????????????????????
??????????????п?????????Java?ж???????????????????????????????????£???????????????????????????????????????????????????????????????????????????????????????????????????????С?????????????????????????????????????
?????????????????????????????????????????Unsafe?к???????????У??????????????????Щ????£????????JNI???????????????????????飬?????????????Σ?????????Java??“??α???????”??????????
??????????????л?
???????????????л?????????????????????????????????????????????÷???????????????ú??????????????????????????????????????final??ε?????????????????????????????????????????????????????????????????????????????????и????á?
????public class A implements Serializable {
????private final int num;
????public A(int num) {
????System.out.println("Hello Mum");
????this.num = num;
????}
????public int getNum() {
????return num;
????}
????}
????????????У????????????????final??Σ?????????ò????ù?????????????????Щ??????л????????顣??????Щ??????????Unsafe???????????????ù???????
????Unsafe unsafe = getUnsafe();
????Class aClass = A.class;
????A a = (A) unsafe.allocateInstance(aClass);
????????allocateInstance????????????????????????????????????????
???????????????????
????Unsafe????????????????????????????檔ByteBuffer????????????????????????DirectMemory?????????????κ????????????????????乲??????????Unsafe???????á?
import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class PingPongMapMain {
public static void main(String... args) throws IOException {
boolean odd;
switch (args.length < 1 ? "usage" : args[0].toLowerCase()) {
case "odd":
odd = true;
break;
case "even":
odd = false;
break;
default:
System.err.println("Usage: java PingPongMain [odd|even]");
return;
}
int runs = 10000000;
long start = 0;
System.out.println("Waiting for the other odd/even");
File counters = new File(System.getProperty("java.io.tmpdir")?? "counters.deleteme");
counters.deleteOnExit();
try (FileChannel fc = new RandomAccessFile(counters?? "rw").getChannel()) {
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE?? 0?? 1024);
long address = ((DirectBuffer) mbb).address();
for (int i = -1; i < runs; i++) {
for (; ; ) {
long value = UNSAFE.getLongVolatile(null?? address);
boolean isOdd = (value & 1) != 0;
if (isOdd != odd)
// wait for the other side.
continue;
// make the change atomic?? just in case there is more than one odd/even process
if (UNSAFE.compareAndSwapLong(null?? address?? value?? value + 1))
break;
}
if (i == 0) {
System.out.println("Started");
start = System.nanoTime();
}
}
}
System.out.printf("... Finished?? average ping/pong took %??d ns%n"??
(System.nanoTime() - start) / runs);
}
static final Unsafe UNSAFE;
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
UNSAFE = (Unsafe) theUnsafe.get(null);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
???????????????????????????odd???????even??????????????????????????????????????????潻????????
??????????????У??????????????????????С??????????????????????????????????ζ??????????????????????????????????????volatile??????CAS?????????????CAS Compare and Swap ????????
???????????????????83ns????????????????System V IPC?????????????????2500ns????????IPC volatile???persisted??棬????????????
????Unsafe???????????????
???????????????????Unsafe????????????Java??????????????????????????黹????t????????????????????????Unsafe????????????????????????н???????????????????Unsafe???????ó????е???÷?????????????????????Unsafe??
???????
????Unsafe??Java???????????????????????????????????????檔??????Щ????????ó??????????д????????????????????t????????Unsafe??????????á?