Java高併發10-Unsafe類中其他方法以及測試

一、複習

  • 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);
 }
}
  • 基本符合預期

四 、源碼:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章