• CAS unSafe的使用


        参考:https://www.cnblogs.com/duanxz/p/6097779.html

    package com.test;
    
    import sun.misc.Unsafe;
    
    import java.lang.reflect.Field;
    
    public class CASLearn {
        private static final Unsafe unsafe;
        private static final long nameOffset;
        private static final long valueOffset;
        private static final long intffset;
    
        //为了保证多线程间的可见性,所以声明为volatile  但是这个例子是单线程的
        private volatile String name;
        private volatile long value;
        private volatile int age;
    
        static {
            try {
                //unsafe无法直接调用Unsafe.getUnsafe()去获取实例,这个方法只对可信任的类才能获取。
                ///通过反射获取unsafe
                Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference
                f.setAccessible(true);
                unsafe = (Unsafe) f.get(null);
    
                //静态代码块初始化每个属性的偏移量
                //CASLearn.class.getDeclaredField("value") 能获取到value属性的原因是java的类加载机制:
                //参考:https://blog.csdn.net/m0_38075425/article/details/81627349
                // 1.加载:读取class二进制流,将类的数据结构存储值方法区,然后新建一个class对象,用来指向该类的数据结构
                // 2.验证:确保Class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身安全。其主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证
                // 3.准备:为类的静态变量分配内存,并设置默认初始值。(int初始值为0)
                // 4.解析:将类的二进制数据中的符号引用替换成直接引用
                // 5.初始化:从上到下,给类的静态变量赋值,包括执行static静态代码块
                valueOffset = unsafe.objectFieldOffset(CASLearn.class.getDeclaredField("value"));
                nameOffset = unsafe.objectFieldOffset(CASLearn.class.getDeclaredField("name"));
                intffset = unsafe.objectFieldOffset(CASLearn.class.getDeclaredField("age"));
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new Error(e);
            }
        }
    
        private CASLearn(String name, long value, int age) {
            this.name = name;
            this.value = value;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "name:" + name + "  age" + age + "   value" + value;
        }
    
        public static void main(String[] args) {
            CASLearn cas = new CASLearn("dh", 100L, 18);
            //原子操作:修改age 18->19
            unsafe.compareAndSwapInt(cas, intffset, 18, 19);
            //原子操作,value的值为100L,不是200L,所以不修改
            unsafe.compareAndSwapLong(cas, valueOffset, 200L, 999L);
            //原子操作,修改"dh"->"hiahiahia"
            unsafe.compareAndSwapObject(cas, nameOffset, "dh", "hiahiahia");
            //结果为:name:hiahiahia  age19   value100
            System.out.println(cas);
        }
    }
  • 相关阅读:
    (收藏)基于.net开发平台项目案例集锦
    记录:在ASP.NET中使用ActiveX插件时遇到的问题
    [转]三种邮件服务器的比较
    (收藏)30岁,开始实现我的程序员梦
    [转]加密狗原理介绍
    从临时表返回数据时遇到的问题(ORA08103: object no longer exists)
    Response.Flush的使用心得
    C#编程向VFP数据库中插入Numeric型的值(foxpro,dbf)
    [转]Web部件错误:此网页存在致命错误
    Win2003Server出现了很多的“桌面”
  • 原文地址:https://www.cnblogs.com/han6/p/11243515.html
Copyright © 2020-2023  润新知