Java多线程进阶(十二)—— J.U.C之atomic框架:Unsafe类

9.jpeg

本文首发于一世流云的专栏: https://segmentfault.com/blog...

1、Unsafe简介

在正式的开讲 juc-atomic框架系列以前,有必要先来了解下Java中的Unsafe类。segmentfault

Unsafe类,来源于sun.misc包。该类封装了许多相似指针操做,能够直接进行内存管理、操纵对象、阻塞/唤醒线程等操做。Java自己不直接支持指针的操做,因此这也是该类命名为Unsafe的缘由之一。框架

J.U.C中的许多CAS方法,内部其实都是Unsafe类在操做。
好比AtomicBooleancompareAndSet方法:
clipboard.pngatom

unsafe.compareAndSwapInt方法是个native方法。(若是对象中的字段值与指望值相等,则将字段值修改成x,而后返回true;不然返回false):
clipboard.pngspa

入参的含义以下:线程

参数名称 含义
o 须要修改的对象
offset 须要修改的字段到对象头的偏移量(经过偏移量,能够快速定位修改的是哪一个字段)
expected 指望值
x 要设置的值

Unsafe类中CAS方法都是native方法,须要经过CAS原子指令完成。在讲AQS时,里面有许多涉及CLH队列的操做,其实就是经过Unsafe类完成的指针操做。3d

2、Unsafe对象的建立

Unsafe是一个final类,不能被继承,也没有公共的构造器,只能经过工厂方法getUnsafe得到Unsafe的单例。
clipboard.png指针

可是getUnsafe方法限制了调用该方法的类的类加载器必须为Bootstrap ClassLoadercode

Java中的类加载器能够大体划分为如下三类:对象

类加载器名称 做用
Bootstrap类加载器(Bootstrap ClassLoader) 主要加载的是JVM自身须要的类,这个类加载使用C++语言实现的,是JVM自身的一部分,它负责将 【JDK的安装目录】/lib路径下的核心类库,如rt.jar
扩展类加载器(Extension ClassLoader) 该加载器负责加载【JDK的安装目录】jrelibext目录中的类库,开发者能够直接使用该加载器
系统类加载器(Application ClassLoader) 负责加载用户类路径(ClassPath)所指定的类,开发者能够直接使用该类加载器,也是默认的类加载器

因此在用户代码中直接调用getUnsafe方法,会抛出异常。由于用户自定义的类通常都是由系统类加载器加载的。blog

可是,是否就真的没有办法获取到Unsafe实例了呢?固然不是,要获取Unsafe对象的方法不少,这里给出一种经过反射的方法:

Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);

可是,除非对Unsafe的实现很是清楚,不然应尽可能避免直接使用Unsafe来进行操做。

相关文章
相关标签/搜索