1.volatile类型修饰符
1)实现可见性:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
- volatile 变量的内存可见性是基于内存屏障Memory Barrier实现。
- 内存屏障:又称内存栅栏,是一个 CPU 指令。
2)实现有序性:禁止进行指令重排序
- 在程序运行时,为了提高执行性能,编译器和处理器会对指令进行重排序,JMM 为了保证在不同的编译器和 CPU 上有相同的结果,通过插入特定类型的内存屏障来禁止特定类型的编译器重排序和处理器重排序,插入一条内存屏障会告诉编译器和 CPU:不管什么指令都不能和这条 Memory Barrier 指令重排序。
3)部分原子性:volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性
volatile 的应用场景
只有在状态真正独立于程序内其他内容时才能使用 volatile
2.AQS模型
- Abstract Queued Synchronizer抽象队列同步器:AQS是JDK下提供的一套用于实现基于FIFO等待队列的阻塞锁和相关的同步器的一个同步框架。
- AQS维护了一个原子变量 volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。许多同步类实现都依赖于它,如常用的ReentrantLock、Semaphore、CountDownLatch…
AQS的核心思想: