001 Unsafe CAS

CAS
  1. CAS (Compare And Swap) 比较和交换
  2. cas(…,oldValue,newValue)方法必定会有两个参数,
  3. 若oldValue与内存中的值一致,就设置内存中的值为newValue,并返回true
  4. 若不致,放弃本次操作,反返回false
  5. CPU保证cas操作的原子性
  6. cas操作需结合自旋,实现一直尝试,直到成功。即CAS方法本身不保证一定成功,但你可以选择再次尝试,直到成功为止。
封装Unsafe工具类,提供三个cas方法
package org.aidan;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * Unsafe 工具类
 */
public class UnsafeUtil {

    private static Unsafe unsafe = null;

    /**
     * 获取unsafe对象
     *
     * @return
     */
    public static Unsafe getUnsafe() {
        if (unsafe == null) {
            synchronized (UnsafeUtil.class) {
                if (unsafe == null) {
                    try {
                        Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
                        unsafeField.setAccessible(true);
                        Unsafe unsafe = (Unsafe) unsafeField.get(null);
                        return unsafe;
                    } catch (NoSuchFieldException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return unsafe;
    }

    public static boolean casInt(Object obj, String fileName, int oldValue, int newValue) {
        try {
            long offset = getOffset(obj, fileName);
            return getUnsafe().compareAndSwapInt(obj, offset, oldValue, newValue);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static boolean casLong(Object obj, String fileName, long oldValue, long newValue) {
        try {
            long offset = getOffset(obj, fileName);
            return getUnsafe().compareAndSwapLong(obj, offset, oldValue, newValue);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static boolean casObject(Object obj, String fileName, Object oldValue, Object newValue) {
        try {
            long offset = getOffset(obj, fileName);
            return getUnsafe().compareAndSwapObject(obj, offset, oldValue, newValue);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return false;
    }

    private static long getOffset(Object obj, String fileName) throws NoSuchFieldException {
        long offset;
        Field field;
        if (obj instanceof Class) {
            Class clazz = (Class) obj;
            field = clazz.getDeclaredField(fileName);
            offset = getUnsafe().staticFieldOffset(field);
        } else {
            field = obj.getClass().getDeclaredField(fileName);
            offset = getUnsafe().objectFieldOffset(field);
        }
        return offset;
    }

}
发布了32 篇原创文章 · 获赞 0 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/h13140995776/article/details/101349211