1.volatile 内存语义

memory semantics

1.1 读-写内存语义

当写一个 volatile 变量时,JMM 会把该线程对应的本地内存中的共享变量值刷新到主内存
当读一个 volatile 变量时,JMM 会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。
总结:

  • 线程 A 写一个 volatile 变量,实质上是线程 A 向接下来将要读这个 volatile 变量的某个线程发出了消息(其对共享变量做出的修改)。
  • 线程 B 读一个 volatile 变量,实质上是线程 B 接收到之前某个线程发出的消息(在写这个 volatile 变量之前对共享变`量所做的修改)。
  • 线程 A 写一个 volatile 变量,随后线程 B 读这个 volatile 变量,这个过程实质上线程 A 通过主内存向线程 B 发送消息。

锁的内存语义 - 图1

2.锁的内存语义

  • 当线程释放锁时,JMM 会把该线程对应的本地内存中的共享变量刷新到主内存中。
  • 当线程获取锁时,JMM 会把该线程对应的本地内存置为无效,从而使得被监视器保护的临界代码必须从主内存中读取共享变量。

3.内存刷新

Ref: https://ddcode.net/2019/04/14/when-does-java-local-memory-refresh-into-main-memory/
线程本地内存刷新到主内存:

  • volatile 关键字
  • synchronized
  • explicit lock in JUC

Use the keyword volatile
when a variable is modified by volatile keyword, the read operation to the shared resource will be directly carried out in the main memory (of course, it will also be cached in the working memory. when other threads modify the shared resource, it will cause the shared resource of the current thread in the working memory to become invalid, so it must be retrieved from the main memory). of course, the write operation to the shared resource must first modify the working memory, but it will be flushed into the main memory immediately after the modification.
Visibility can be guaranteed through the synchronized keyword
synchronized keyword can ensure that only one thread obtains the lock at the same time, then executes the synchronization method, and also ensures that changes to variables are refreshed into main memory before the lock is released.
The visibility can also be guaranteed by the explicit Lock provided by JUC
the Lock method of Lock can ensure that only one thread obtains the lock and then executes the synchronization method at the same time, and can ensure that changes to variables are refreshed into main memory before the lock is released (unlock method of lock).