博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
保证多线程间的可见性,所以声明为volatile
阅读量:5311 次
发布时间:2019-06-14

本文共 2384 字,大约阅读时间需要 7 分钟。

  参考: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);    }

转载于:https://www.cnblogs.com/struohnssebxsc/p/11243549.html

你可能感兴趣的文章
Excel-基本操作
查看>>
面对问题,如何去分析?(分析套路)
查看>>
Excel-逻辑函数
查看>>
面对问题,如何去分析?(日报问题)
查看>>
数据分析-业务知识
查看>>
nodejs vs python
查看>>
poj-1410 Intersection
查看>>
Java多线程基础(一)
查看>>
TCP粘包拆包问题
查看>>
Java中Runnable和Thread的区别
查看>>
SQL Server中利用正则表达式替换字符串
查看>>
POJ 1015 Jury Compromise(双塔dp)
查看>>
论三星输入法的好坏
查看>>
Linux 终端连接工具 XShell v6.0.01 企业便携版
查看>>
JS写一个简单日历
查看>>
LCA的两种求法
查看>>
Python 发 邮件
查看>>
mysql忘记密码的解决办法
查看>>
全面分析Java的垃圾回收机制2
查看>>
[Code Festival 2017 qual A] C: Palindromic Matrix
查看>>