https://blog.csdn.net/dfdsggdgg/article/details/51543545
http://ifeve.com/sun-misc-unsafe/
目录
1、实例化私有私有类,以及根据偏移量修改内存数据
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class MainNioTest {
public static void main(String[] args) {
// 通过反射实例化Unsafe
Field f;
try {
f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
// 实例化Player
Player player = (Player) unsafe.allocateInstance(Player.class);
player.setAge(18);
player.setName("li lei");
for (Field field : Player.class.getDeclaredFields()) {
System.out.println(field.getName() + ":对应的内存偏移地址" + unsafe.objectFieldOffset(field));
}
System.out.println("-------------------");
int ageOffset = 12;
// 修改内存偏移地址为12的值(age),返回true,说明通过内存偏移地址修改age的值成功
System.out.println(unsafe.compareAndSwapInt(player, ageOffset, 18, 20));
System.out.println("age修改后的值:" + player.getAge());
System.out.println("-------------------");
// 修改内存偏移地址为12的值,但是修改后不保证立马能被其他的线程看到。
unsafe.putOrderedInt(player, 12, 33);
System.out.println("age修改后的值:" + player.getAge());
System.out.println("-------------------");
// 修改内存偏移地址为16的值,volatile修饰,修改能立马对其他线程可见
unsafe.putObjectVolatile(player, 16, "han mei");
System.out.println("name修改后的值:" + unsafe.getObjectVolatile(player, 16));
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Player{
private int age;
private String name;
private Player(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2、超级数组:
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class MainNioTest {
public static void main(String[] args) {
// 通过反射实例化Unsafe
Field f;
try {
f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
// 只要内存够大,可以把这个调大,大于Integer.MAX_VALUE
long size = (long) Integer.MAX_VALUE * 2;
long addr = unsafe.allocateMemory(size);
System.out.println("unsafe address :" + addr);
for (int i = 0; i < size; i++) {
unsafe.putByte(addr + i, (byte) 6);
if (unsafe.getByte(addr + i) != 6) {
System.out.println("failed at offset");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}