unsafe这个类是Jdk中底层的一个类,主要可以用于操作底层的内存,cas,数组,对象,内存操作,等一些可以跨过JVM底层操作。也就是因为能够对内存操作,自然就会引发一些不安全问题。所有叫做unsafe。
unsafe是不能new的因为它的构造函数是私有的,另外如果要使用getUnsafe()这个方法,就必须要保证类加载器是启动类加载器,
private Unsafe() {
}
@CallerSensitive
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
还有获取unsafe这个类的实例的方法是通过反射;
public static Unsafe reflectGetUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
1. 内存操作
内存操作类似于C++中的malloc方法,需要自己手动分配内存和释放内存。
public static void main(String[] args) {
Unsafe unsafe = UnsafeInstance.reflectGetUnsafe();
long oneHundred = 1;
byte size = 1;
/*
* 调用allocateMemory分配内存
*/
long memoryAddress = unsafe.allocateMemory(size);
/*
* 将1写入到内存中
*/
unsafe.putAddress(memoryAddress, oneHundred);
/*
* 内存中读取数据
*/
long readValue = unsafe.getAddress(memoryAddress);
System.out.println("value : " + readValue);
}
CAS操作
cas操作是并发编程中的核心,也是在unsafe类中实现的。底层是基于CMPXCHG指令的操作。
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
可以实现根据偏移量地址找到变量实现原子操作。
public class AtomicStudentAgeUpdater {
private String name ;
private volatile int age;
private static final Unsafe unsafe = UnsafeInstance.reflectGetUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset(AtomicStudentAgeUpdater.class.getDeclaredField("age"));
System.out.println("valueOffset:--->"+valueOffset);
} catch (Exception e) {
throw new Error(e);
}
}
public void compareAndSwapAge(int old,int target){
unsafe.compareAndSwapInt(this,valueOffset,old,target);
}
public AtomicStudentAgeUpdater(String name,int age){
this.name = name;
this.age = age;
}
public int getAge(){
return this.age;
}
public static void main(String[] args) {
AtomicStudentAgeUpdater updater = new AtomicStudentAgeUpdater("杨过",18);
updater.compareAndSwapAge(18,56);
System.out.println("真实的杨过年龄---"+updater.getAge());
}
}
输出
valueOffset:--->12
真实的杨过年龄---56
线程调度
public native void unpark(Object var1);
public native void park(boolean var1, long var2);
/** @deprecated */
@Deprecated
public native void monitorEnter(Object var1);
/** @deprecated */
@Deprecated
public native void monitorExit(Object var1);
/** @deprecated */
@Deprecated
public native boolean tryMonitorEnter(Object var1);
park和unpark是线程挂起和恢复操作。
内存屏障
public native void loadFence();
public native void storeFence();
public native void fullFence();
CPU和编译器堆内存随机访问操作的同步点,此点之前的所有的读写操作都执行之后才进行之后的操作。避免了指令重排序。
islandlxl 发布了9 篇原创文章 · 获赞 1 · 访问量 619 私信 关注