1、複習
-
synchronized和volatile的不一樣點,相同點
-
volatile不能保證原子性,只能保證內存可見性
-
-
-
-
unsafe類中的boolean objectFieldOffset(Field field),boolean compareAndSwapLong(Object obj,long offset,long expect,long update),int arrayBaseOffset(Class arrayClass),int arrayIndexOffset(Class arrayClass)
2、Unsafe類中的其餘方法
1.public native long getLongvolatile(Object obj,long offset)
-
該方法用於獲取對象obj地址偏移量爲offset長度的對應volatile語義的值
2.void putLongvolatile(Object obj,long offset,long value)
-
該方法用於在對象obj地址偏移量爲offset長度的類型爲long的field值設置爲value,支持volatile
3.void putOrderedLong(Object obj,long offset,long value)
-
該方法用於在對象obj地址偏移量爲offset長度的類型爲long的field值設置爲value,這是一個有延遲的putLongvolatile方法,而且不能保證其餘線程也能看到,只有被volatile修飾並有可能被意外修改的時候纔會使用這個方法
4.void park(boolean isAbsolute,long time)
-
若是isAbsolute爲false,time=0,表示當前線程一直阻塞
-
若是isAbsolute爲false,time>0,表示當前線程阻塞time時間後,會被喚醒
注意:這時的time是一個時間段,也就是調用開始到time用完git
-
若是isAbsolute爲true,time>=0,表示當前線程time時間後阻塞中止,被喚醒,這裏的time是絕對時間,會換算稱ms單位的一個時間點
-
另外當其餘線程調用了該線程的nterrupt()方法以後,該線程會返回;
-
若是其餘線程調用了unpark方法,而且把該線程做爲參數傳入unpark方法中,那麼該線程也會返回
5.void unpark(Thread thread)
-
喚醒調用park方法的阻塞狀態的thread線程。
6.long getAndSetLong(Object obj,long offset,long update)
-
獲取對象obj中偏移量爲offset的變量volatile語義的當前值,而且設置volatile語義的值爲update
public final long getAndSetLong(Object obj,long offset,long update){
long l;
do{
l=getLongvolatile(obj,offset);
}while(!compareAndSwapLong(obj,offset,l,update);
return l;
}
-
這裏的循環是考慮到在多線程的環境下CAS操做會出現失敗的狀況,所以屢次判斷一下獲取正確的值
7.long getAndAddLong(Object obj,long offset,long addValue)
-
該函數用於獲取對象obj在其偏移量爲offset的volatile變量的語義,而且該值賦值爲原值加addValue
public final long getAndAddLong(Object obj,long offset,long addValue){
long l;
do{
l = getLongvolatile(obj,offset);
}while(!compareAndSwapLong(obj,offset,l,l+addValue);
return l;
}
3、直接對Unsafe類舉例
package com.ruigege.OtherFoundationOfConcurrent2;
import jdk.internal.misc.Unsafe;
public class TestUnsafe {
static final Unsafe unsafe = Unsafe.getUnsafe();
static final long state = 0;
static final long stateOffset=0;
static {
try {
stateOffset = unsafe.objectFieldOffset(Unsafe.class.getDeclaredField("state"));
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestUnsafe testUnsafe = new TestUnsafe();
Boolean success = unsafe.compareAndSwapInt(testUnsafe,stateOffset,0,1);
System.out.println(success);
}
}
四 、源碼:
-
所在包:com.ruigege.OtherFoundationOfConcurrent2
-
https://github.com/ruigege66/ConcurrentJava
-
-
-
歡迎關注微信公衆號:傅里葉變換,我的帳號,僅用於技術交流