一、復習
synchronized和volatile的不同點,相同點 volatile不能保證原子性,只能保證記憶體可見性 volatile在什么情況下可以使用(兩種情況) ABA問題定義,產生原因以及消除方法 Java中的CAS操作 unsafe類中的boolean objectFieldOffset(Field field),boolean compareAndSwapLong(Object obj,long offset,long expect,long update),int arrayBaseOffset(Class arrayClass),int arrayIndexOffset(Class arrayClass)
二、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用完
如果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;
}
三、直接對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;
//unsafe實體內部屬性state的偏移量
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/ConcurrentJavaCSDN:https://blog.csdn.net/weixin_44630050 博客園:https://www.cnblogs.com/ruigege0000/ 歡迎關注微信公眾號:傅里葉變換,個人賬號,僅用于技術交流 
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/227727.html
標籤:其他
上一篇:關于在Linux服務器上用BufferedImage.getGraphics()得到的Graphics物件是null的問題,求解決
下一篇:JSP課程設計資料庫設計
