一、锁的内存语义
所为的java内存模型的内存语义指的就是在JVM中的实现原则。
锁的内存语义:锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息。
我们把上面这句话再整理下:
当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。
当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须要从主内存中去读取共享变量。
锁的内存语义实现:
synchronized、ReentrantLock;
二、volatile内存语义
volatile的内存语义与锁的内存语义相识:
1.当写一个volatile变量时,java内存模型会吧线程对应的本地内存中的共享变量刷新到主内存中。
2.当读一个volatile变量时,java内存模型会把当前线程对应内存中的共享变量置为无效 ,然后在主内存中读取共享变量。
我们可以看到volatile写的内存语义和释放锁的内存语义类似,volatile读的内存语义和获取锁的内存语义类似。
三、final的内存语义
final域的内存语义主要是研究其指令重排序规则,主要分为写、读两种指令重排序规则
1.写final域的指令重排序规则
①写final域的重排序规则禁止把final域的写重排序到构造方法外
②静态代码块中不能对常量赋值,因为静态代码块是在类加载时生成的,常量是类初始化创建的。我们知道,类的加载中,加载先与初始化进行,所有不能。
③编译器会在final域的写之后,在构造方法执行完毕之前,插入一个内存屏障 store store,保证出来器把final域的写操作在构造方法中执行。
2.读final域的重排序规则
在一个线程中,初次读对象引用和初次读该对象所包含的final域,java内存模型禁止处理器重排这两个操作。