多线程 Unsafe类的使用

Unsafe类提供了原子性操作CAS

package com.example.demo.utils;

import com.alibaba.druid.pool.DruidDataSource;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.*;

public class Test1 {

static Unsafe unsafe; //sun.misc.Unsafe
static long stateOffset;
private volatile long state = 0;

public Test1() {
}

static {
try {
//因为Unsafe的类加载和项目中的类加载器bootstrap不一样,Unsafe的getUnsafe()判断了类加载器不同会报错,所以需要使用反射获取unsafe实例
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
//获取state变量在test1中的内存偏移量
stateOffset = unsafe.objectFieldOffset(Test1.class.getDeclaredField("state"));
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
e.printStackTrace();
}
}

public static void main(String args[]) {
Test1 test1 = new Test1();
System.out.println("first:"+stateOffset);
System.out.println(test1.state);
long state = test1.state;//此时state为0
//非阻塞算法CAS操作,在系统层面把该操作锁住,禁止中途被其他线程修改。
// 操作失败代表中途有人截胡,把state的值改了
//这样就可以知道数据被改动,可以预防产生脏数据
Boolean sucess = unsafe.compareAndSwapLong(test1, stateOffset, state,1);
System.out.println(sucess);

System.out.println("2rd:"+stateOffset);
System.out.println(test1.state);



}
}

Unsafe的部分其他方法
public native long staticFieldOffset(Field var1);

public native long objectFieldOffset(Field var1);

public native Object staticFieldBase(Field var1);

public native boolean shouldBeInitialized(Class<?> var1);

public native void ensureClassInitialized(Class<?> var1);

public native int arrayBaseOffset(Class<?> var1);

public native int arrayIndexScale(Class<?> var1);
public native long getLongVolatile(Object var1, long var2);

public native void putLongVolatile(Object var1, long var2, long var4);
public native void putOrderedInt(Object var1, long var2, int var4);

public native void putOrderedLong(Object var1, long var2, long var4);

public native void unpark(Object var1);

public native void park(boolean var1, long var2);
posted @ 2019-12-29 10:10  覃上  阅读(425)  评论(0编辑  收藏  举报