Unsafe
Unsafe 是 CAS 的核心类,由于 Java 无法直接访问底层系统,需要通过本地(Native)方法来访问
Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。
Unsafe类中的重要方法
Unsafe类提供了硬件级别的的原子性操作,Unsafe类中的方法都是native方法,通过使用JNI的方式访问本地C++库
- long objectFieldOffset(Field field) 方法: 返回指定的变量在所属类中的内存偏移地址
- int arrayBaseOffset(Class arrayClass) 方法: 获取数组中第一个元素的地址
- boolean compareAndSwapLong(Object obj, long offset, long expect, long update) 方法: CAS操作
- public native long getLongvolatile(Object obj, long offset) 方法: 获取对象obj中偏移量offset 的变量对应volatile语义的值
- void putLongvolatile(Object obj, long offset, long value)方 法: 设置 obj 对 象 中 offset偏移的类型为 long 的 field 的值为 value ,支持 volatile 语义
- void park(boolean isAbsolute, long time) 方法: 阻塞当前线程
- void unpark(Object thread) 方法: 唤醒调用park后阻塞的线程
- long getAndSetLong(Object obj , long offset, long update) 方法: 获取对象 obj 中偏移量为offset 的变量 volatile语义的当前值 ,并设置变量 volatile 语义的值为 update
- long getAndAddLong(Object obj, long offset, long addValue) 方法: 获取对象obj中偏移量为 offset 的变量 volatile 语义的当前值 ,并设置变量值为原始值+addValue
模拟实现原子整数
Unsafe类为一单例实现,提供静态方法getUnsafe获取Unsafe实例,当且仅当调用getUnsafe方法的类为引导类加载器所加载时才合法,否则抛出SecurityException异常。
1 | public static void main(String[] args) { |