Unsafe 類方法介紹
1. 前言
本節內容主要是對 Unsafe 類方法進行介紹,JDK jar 包中的 Unsafe 類提供了硬件級別的原子性操作,Unsafe 類中的方法都是 native 方法,它們使用 JNI 的方式訪問本地 C++實現庫。
本節我們來了解一下 Unsafe 提供的幾個主要的方法進行介紹。為我們后續對 Unsafe 方法的使用奠定良好的基礎。
2. 方法介紹
方法 | 作用 |
---|---|
objectFieldOffset(Field) | 返回指定的變量在所屬類中的內存偏移地址,該偏移地址僅僅在該 UnSafe 函數中訪問指定字段時使用。 |
arrayBaseOffset(Class) | 獲取取數組中第一個元系的地址。 |
arrayIndexScale(Class) | 獲取數組中一個元素占用的字節。 |
compareAndSwapLong(Object,long,long,long) | 比較對象 obj 中偏移量為 offset 的變量的值是否與 expect 相等,相等則使用 update 值更新,然后返回 true,否則返回 false。 |
longgetLongvolatile(Object,long) | 獲取對象 obj 中偏移量為 offset 的變量對應 volatile 語義的值。 |
void putLongvolatile(Object,long,long) | 設置 obj 對象中 offset 偏移的類型為 long 的 field 的值為 value, 支持 volatile 語義。 |
putOrderedLong(Object,long,long) | 設置 obj 對象中 offset 偏移地址對應的 long 型 field 的值為 value。這是一個有延遲的 putLongvolatile 方法,并且不保證值修改對其他線程立刻可見。只有在變量使用 volatile 修飾并且預計會被意外修改時才使用該方法。 |
unpark(Object) | 喚醒調用 park 后阻塞的線程。 |
3. park 方法介紹
方法描述: void park(booleanisAbsolute,longtime):阻塞當前線程,其中參數 isAbsolute 等于 false 且 time 等于 0 表示一直阻塞。
方法解讀:time 大于 0 表示等待指定的 time 后阻塞線程會被喚醒,這個 time 是個相對值,是個增量值,也就是相對當前時間累加 time 后當前線程就會被喚醒。如果 isAbsolute 等于 true,并且 time 大于 0,則表示阻塞的線程到指定的時間點后會被喚醒。
這里 time 是個絕對時間,是將某個時間點換算為 ms 后的值。另外,當其他線程調用了當前阻塞線程的 interrupt 方法而中斷了當前線程時,當前線程也會返回,而當其他線程調用了 unPark 方法并且把當前線程作為參數時當前線程也會返回。
4. JDK8 新增的函數
方法 | 作用 |
---|---|
getAndSetLong(Object, long, long) | 獲取對象 obj 中偏移量為 offset 的變量 volaile 語義的當前值,并設置變量 volaile 語義的值為 update。 |
getAndAddLong(Object,long,long) | 方法獲取 object 中偏移量為 offset 的 volatile 變量的當前值,并設置變量值為原始值加上 addValue |
5. 小結
本節的核心內容即 Usafe 方法的了解,為下邊講解 Unsafe 方法的使用奠定一個良好的基礎。