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來進行操做。

相關文章
相關標籤/搜索