Unsafe类是在sun.misc包下,不属于Java标准。但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty、Cassandra、Hadoop、Kafka等。Unsafe类在提升Java运行效率,增强Java语言底层操作能力方面起了很大的作用。
Unsafe类是java中非常特别的一个类。它名字就叫做“不安全”,提供的操作可以直接读写内存、获得地址偏移值、锁定或释放线程。通过正常途径是无法获得Unsafe实例的,首先它的构造方法是私有的,然后,即使你调用它的getUnsafe方法,也会抛出SecurityException。
public static void main(String[] args) throws Exception {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe u = (Unsafe) f.get(null);
System.out.println(u);
int[] arr = {1,2,3,4,5,6,7,8,9,10};
int b = u.arrayBaseOffset(int[].class);
System.out.println(b);
int s = u.arrayIndexScale(int[].class);
System.out.println(s);
u.putInt(arr, (long)b+s*9, 1);
for(int i=0;i<10;i++){
int v = u.getInt(arr, (long)b+s*i);
System.out.print(v+" ");
}
}
打印结果:1 2 3 4 5 6 7 8 9 1 ,可以看到,成功读出了数组中的值,而且最后一个值由10改为了1。
arrayBaseOffset: 返回当前数组第一个元素地址相对于数组起始地址的偏移值,在本例中返回6。
arrayIndexScale: 返回当前数组一个元素占用的字节数,在本例中返回4。
putInt(obj,offset,intval): 获取数组对象obj的起始地址,加上偏移值,得到对应元素的地址,将intval写入内存。
getInt(obj,offset): 获取数组对象obj的起始地址,加上偏移值,得到对应元素的地址,从而获得元素的值。
偏移值: 数组元素偏移值 = arrayBaseOffset + arrayIndexScalse * i。
参考:
https://www.cnblogs.com/pkufork/p/java_unsafe.html
https://www.jianshu.com/p/9819eb48716a