: http://mydailyjava.blogspot.it/2013/12/sunmiscunsafe.html
Unsafe ,
getXXX (Object target, long offset): XXX .
getXXXVolatile (Object target, long offset): XXX .
putXXX (Object target, long offset, XXX value): .
putXXXVolatile (Object target, long offset, XXX value): .
UPDATE:
: http://cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html ( ).
, ( ), ( .) , . , , , ? ?
, . , , , , , , .
, , . , , ; . , ; , "" .
Java , , , concurrency . Java , , Java- .
volatile?
- , . , ; , , "" . . , , . , volatile , , , .
. . . , , , . , , , , A, f, B, f.
, , setXXX() getXXX() , , setXXXVolatile() getXXXVolatile() .
- , java : / / , .
, , . - , , : , , ( ).
.
, ( , ).
setXXX() , , . , , , . . setXXXVolatile() , ( getXXXVolatile()).
getXXX(), . , , , . getXXXVolatile(), , .
:
class DirectIntArray {
private final static long INT_SIZE_IN_BYTES = 4;
private final long startIndex;
public DirectIntArray(long size) {
startIndex = unsafe.allocateMemory(size * INT_SIZE_IN_BYTES);
unsafe.setMemory(startIndex, size * INT_SIZE_IN_BYTES, (byte) 0);
}
}
public void setValue(long index, int value) {
unsafe.putInt(index(index), value);
}
public int getValue(long index) {
return unsafe.getInt(index(index));
}
private long index(long offset) {
return startIndex + offset * INT_SIZE_IN_BYTES;
}
public void destroy() {
unsafe.freeMemory(startIndex);
}
}
putInt getInt , ( ).
, , . , setValue(), , ( JVM).
.
.
DirectIntArray directIntArray = new DirectIntArray(maximum);
Runnable t1 = new MyThread(directIntArray);
Runnable t2 = new MyThread(directIntArray);
new Thread(t1).start();
new Thread(t2).start();
MyThread:
public class MyThread implements Runnable {
DirectIntArray directIntArray;
public MyThread(DirectIntArray parameter) {
directIntArray = parameter;
}
public void run() {
call();
}
public void call() {
synchronized (this) {
assertEquals(0, directIntArray.getValue(0L));
directIntArray.setValue(0L, 10);
assertEquals(10, directIntArray.getValue(0L));
}
}
}
putIntVolatile() getIntVolatile() ( 10 0).
putInt() getInt() ( 0, ).