java线程内存模型JMM
线程共享变量存储在主内存中,每个线程都有自己的本地内存,内部存有共享变量的副本,本地内存是一个抽象概念,它是缓存、寄存器、硬件和编译器优化的合集。
保证内存可见性:内存模型的happens-before规则,也就是前一个操作执行的结果对后一个操作可见(并不保证前一个操作在后一个操作前执行,这是java在首先保障结果正确的前提下做出的允许编译器和硬件优化让步),要求happens-before规则的场景有:同一个线程的先后语句、加锁和解锁、对volatile变量的写要先于读、规则的传递性。
as-if-serial语义:指令重排序不影响单线程程序执行的结果
volatile之所以可以保证可见性是因为它把单个变量的读写操作加锁了,happens-before规则使其拥有可见性,任何线程都会读到刚刚写入的volatile变量。写入volatile变量时会把线程本地内存的共享变量刷新到主存。
AQS底层依赖的就是volatile修饰的state变量,采用CAS来修改state变量,再利用原子读写,来确保JUC的实现。
final有一个特点,不能使用默认初始化,要么在定义时初始化,要么在构造函数中初始化。这是为了保护其他线程不读到final未初始化的数据。对于final的值写入和赋值引用是禁止指令重排的,读到包含final的对象和读取final域也是禁止指令重排的,为的就是保护final。