前言上一节我们了解了synchronized关键字的底层原理和锁升级过程。本节带你了解CPU多核硬件架构和Java内存模型CPU多核硬件架构解析CPU每次从主内存读取数据的速度很慢,CPU通常会涉及到多级缓存。CPU读取主存中的数据,根据空间局部性原理将部分快照加载到缓存中。L1和L2在每个CPU中属于独立的缓存,将共享变量的数据作为副本缓存在主存中。L3属于多个CPU。共享缓存。每个CPU都有独立的二级缓存主存数据作为副本,副本之间有完全不可见的总线仲裁机制。处理器和内存之间的每一次数据传输都是通过一系列的步骤完成的,这一系列的步骤被称为总线事务(BusTransaction),总线会同步尝试并发使用总线的事务。处理器在执行总线事务期间,总线会禁止其他处理器和I/O设备进行内存读/写。总线的这种工作机制可以将所有处理器对内存的访问序列化。在任何时间点,最多有一个处理器可以访问内存。此功能可确保单个总线事务中的内存读/写操作是原子的。处理器提供总线锁和缓存锁两种机制,保证复杂内存操作的原子总线锁。总线锁是使用处理器提供的LOCK#。信号,当其中一个处理器在总线上输出这个信号时,其他处理器的请求就会被阻塞,这时该处理器就可以独占共享内存了。总线锁定会将并行程序变为串行缓存锁定。缓存锁定是当一个CPU改变缓存的数据时,它会通知已经缓存数据的CPU丢弃缓存的数据或者重新从内存中读取。读写时,必须按协议操作。此类协议包括MSI、MESI、MOSI、Synapse、Firefly和DragonProtocol等,但使用最多的是MESI。缓存一致性协议会对缓存行进行加锁,其性能远高于加锁总线。MESIprotocolMModified(修改)该行数据有效,数据被修改,与主存中的数据不一致,数据只存在于这个Cache中。EExclusive,exclusive(Exclusive)这行数据有效,数据与主存中的数据一致,数据只存在于本Cache中。S共享(Shared)这行数据有效,数据与主存中的数据一致,数据存在于很多缓存中。I无效(Invalid)该行的数据无效。JMM内存模型主内存存放我们共享变量的数据工作内存每个CPU都有一份共享变量(主内存)JMM八同步规范读取(read):从主内存读取数据加载(load):加载mainmemory将读取的数据写入工作内存use(use):从工作内存中读取数据进行计算assign(赋值):将计算出的值重新赋值到工作内存store(存储):写入工作内存数据Mainmemorywrite(write):将store过去的变量值赋值给主存中的变量lock(lock):锁定主存变量,标记线程独占状态unlock(unlock):解锁主存变量,unlock之后,其他线程可以锁定变量。并发的三个主要特征是可见性、原子性和顺序。可见性是指当一个线程修改共享变量的值时,其他线程是否可以立即知道修改后的值如何通过volatile关键字保证可见性通过内存屏障保证可见性通过synchronized关键字保证可见性。通过Lock保证可见性通过final关键字保证可见性的顺序,即程序执行的顺序是按照代码的先后顺序执行的。JVM有指令重排,所以有顺序问题。在多线程环境下,操作是无序的,工作内存和主内存之间存在指令重排现象和同步延迟。如何保证秩序?使用volatile关键字来确保可见性。使用内存屏障来确保可见性。使用synchronized关键字保证有OrderingisguaranteedbyLockAtomicity原子性意味着一个操作是不可中断的。即使在多线程环境下,一个操作一旦开始,也不会受到其他线程的影响。如何保证原子性由synchronized关键字保证Atomicity由Lock保证Atomicity由CAS保证
