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

四 、源码:

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