多线程-volatile
volatile主要用途
1、保证可见性
对volatile变量的写指令后会加入写屏障
写屏障:在屏障之前的对共享变量的改动都同步到主存
对volatile变量的读指令前会加入读屏障
读屏障:在该屏障之后对共享变量的读取加载的都是主存中的新数据
2、保证有序性
写屏障保证指令重排序时,不会讲写屏障之前的代码派到写屏障之后
读屏障保证指令重排序时,不会讲读屏障之后的代码排到读屏障之前
不能解决多个线程并发执行指令交错的问题

上面的代码中会有指令重排序的问题
对应的字节码文件

可能会被优化为先执行24(赋值),再执行21(调用对象的构造方法)
当线程A进入同步代码块时,先执行赋值操作,但是还没有调用对象的构造方法,此时线程b进入了方法,由于判断不为空会直接拿到还没有初始化完全的对象,从而产生问题
synchronized可以保证有序性,但是前提是需要将对象完全交给synchronized管理,在上面的代码中由于代码块中还有对 对象 的操作,所以会有问题
(CAS需要借助volatile才能读取到共享变量的最新值来实现【比较并交换】)
在AtomicInteger中 value 就被volatile修饰

原子引用:
利用CAS思想
AtomicReference
AtomicStampedReference 解决CAS产生的ABA问题 可以设置版本号
AtomicMarkableReference 用boolean 来表示是否被更改过
如果只是单纯的累加操作 LongAdder 的性能要比AtomicLong要更好,在有多个线程竞争时,设置多个累加单元cell[i](数量不会超过cpu核心数,只有cpu拥有多个核心数CAS才有意义),最后讲结果汇总。这样他们累加的时候操作的是不同的cell变量,减少了CAS重试失败。

浙公网安备 33010602011771号