自定义cas操作类

cas操作

在jdk1.8 的java.util.concurrent包下很多类都有cas操作,来保证操作原子性

自定义cas操作类_第1张图片

自定义cas操作类_第2张图片

可以看到是Unsafe类里面的方法,而且都是native方法。

根据这些代码 模拟一个cas操作类试试看
此类需要的:
Unsafe 属性 unsafe 
volatile修饰的属性 state
state在内存中的位置 stateOffset
期望值(state的初始值0) 
修改值 1

import sun.misc.Unsafe;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class CustomCas {

    //unsafe属性
    private static final Unsafe unsafe = Unsafe.getUnsafe();

    //volatile修饰的状态属性字段
    private volatile int state;

    //state在内存中的位置
    private static final long stateOffset;
    static {
        try {
            stateOffset = unsafe.objectFieldOffset(CustomCas.class.getDeclaredField("state"));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new Error(e);
        }
    }

    /**
     * 测试方法
     * @param obj 对象
     * @param expect 期望值
     * @param update 更新值
     * @return boolean
     */
    public String testCas(Object obj,int expect,int update){
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        boolean b = unsafe.compareAndSwapInt(obj, stateOffset, expect, update);
        return "线程:" + Thread.currentThread().getName() + " " + "结果:" + b;
    }
     
 public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        CustomCas customCas = new CustomCas();
        //0 设置为1
        for (int i = 0; i < 5; i++) {
            String o = executorService.submit(()->customCas.testCas(customCas, 0, 1)).get();
            System.out.println(o);
        }
        //1 设置为0
        for (int i = 0; i < 5; i++) {
            String o = executorService.submit(()->customCas.testCas(customCas, 1, 0)).get();
            System.out.println(o);
        }
    }
}

运行

自定义cas操作类_第3张图片

点击查看

自定义cas操作类_第4张图片

自定义cas操作类_第5张图片

这个注解  CallerSensitive  这个方法  Reflection.getCallerClass(); 获取当前调用方法的class对象,大概意思就是 

我们自定义的代码使用的是AppClassLoader类加载器 出于安全是没有权限访问这个方法的。凉凉!!

然后想到可以试一下反射获取, 写个方法试试

/**
 * 自定义获取Unsafe的theUnsafe实例
 * @return
 */
private static Unsafe getUnsafe(){
    Class cla =  Unsafe.class;
    try {
        Field theUnsafe = cla.getDeclaredField("theUnsafe");
        theUnsafe.setAccessible(true);
        Unsafe theUnsafeObj = (Unsafe) theUnsafe.get(null);
        return theUnsafeObj;
    } catch (NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
    }

    return null;
}

 

自定义cas操作类_第6张图片

改成这样再跑一下

自定义cas操作类_第7张图片

 

你可能感兴趣的:(juc)