volatile
Volatile关键字修饰,线程A改变主内存flag = flase,会通知线程B去主内存重新读取flag = flase(缓存过期通知)
Volatile 如何解决指令重排序?
a、java 代码层面 :volatile
b、java字节码层面 :acc_volatile 标记
c、jvm层级内存屏障:屏障两边的指令不可以重排,保证有序性。
d、最底层汇编语言实现 lock 指令
1、线程可见性,底层实现 缓存行对齐, catch line 64字节,MESI缓存行一致性协议
2、禁止指令重排序 ——》DCL单例
避免乱序执行
1、jvm层级内存屏障(一种cpu指令):屏障两边的指令不可以重排,保证有序性。
2、cpu层级 lock指令
Synchronized实现
1、java 代码层面 :synchronized
2、java字节码层面 :开始加 monitorenter监视器,结束moniterexit 退出
3、执行过程中锁自动升级(无锁——》偏向锁——》自旋锁——》重量级锁)
4、最底层汇编语言实现 lock comxchg 指令
volatile synchronized 区别?
- Volatile 只能保证可见性
- Synchronized 既能保证可见性又能保证原子性
Synchronized vs Lock(CAS)
在高竞争中 高耗时环境下 synchronized效率更高
在低竞争中 低耗时的环境下CAS效率更高
Synchronized到重量级锁之后是等待队列(不消耗CPU)
CAS(等待极其消耗CPU)
Synchronized 与 ReentrantLock 的区别。公平锁
Lock lock=new ReentrantLock(); try { lock.lock(); } finally { lock.unlock(); }
ReentrantLock 必须在 finally 块中释放。否则,如果受保护的代码将抛出异常,锁就有可能永远得不到释放!
ReentrantLock 构造器的一个参数是 boolean 值 。可实现公平锁