1. 可见性, 原子性与有序性

1.1 可见性

volatile 是java的一个关键字, 提供了一种轻量级的同步机制, 能保证可见性, 但不保证原子性, 通过禁止指令重排来保证有序性.

可见性: 通过实现缓存一致性协议来保证

每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器对这个数据进行修改操作的时候,会重新从系统内存中把数据读到处理器缓存里。因此,经过分析我们可以得出如下结论:

  1. Lock前缀的指令会引起处理器缓存写回内存;
  2. 一个处理器的缓存回写到内存会导致其他处理器的缓存失效;
  3. 当处理器发现本地缓存失效后,就会从内存中重读该变量数据,即可以获取当前最新值。

这样针对volatile变量通过这样的机制就使得每个线程都能获得该变量的最新值。

链接:https://www.jianshu.com/p/157279e6efdb

JMM(java内存模型)规定:

1.线程解锁前, 必须把共享变量的值刷新回主内存

2.线程加锁前, 必须读取主内存的最新值到工作内存

3.加锁和解锁必须为同一把锁

1.2 原子性

如何保证原子性: i++这种操作并不是原子性操作, 所以要么加锁(如synchronized, Lock) 要么使用AtomicXXX类;

AtomicXXX类实现原理是CAS

1.3 有序性

https://z3.ax1x.com/2021/06/17/2zIyFI.png

为了保证有序性, volatile利用内存屏障(memory barrier) 来实现禁止指令重排