Java Visibility Memory model
- Memory
- Local memory
- Private memory per thread
- java 的所有变量都存储在主内存中- 每个线程有自己独的工作内存,保存了该线程使用到的变量副本,是对主内存中变量的一份拷贝- 每个线程不能访问其他线程的工作内存,线程间变量传递需要通过主内存来完成- 每个线程不能直接操作主存,只能把主存的内容拷贝到本地内存后再做操作(这是线程不安全的本质),然后写回主存
Method of visibility volatile
This way, you can guarantee that each fetch is directly from the primary access
It only guarantees the visibility of the memory and does not guarantee atomicity
It does not need to be locked, is more lightweight than synchronized, does not block threads
Will not be optimized by the compiler
However, it is necessary to do atomic operations on this variable, otherwise there will be problems
Although volatile is lightweight, it also needs to ensure that the order of read and write is not disorderly, so there can be optimization points, such as in the singleton implementation of the double check, using the 临时变量
reduction of volatile variable access.
Synchronized
Synchronized can achieve atomicity and visibility; in the Java memory model, Synchronized rules that when a thread is locked, it empties the working memory → copies the latest variable in main memory to the working memory → executes the code → refreshes the value of the changed shared variable into main memory → Releases the mutex lock.
So if you can't do visibility with volatile, you can consider the guarantee of visibility with synchronized.
Atomicxxx
The JDK provides a number of atomic types, and this type of rationale sums up the volatile + unsafe Compare and Swap, which is not recommended for use in your own code, because the JDK versions vary greatly here, and it is possible to upgrade the JDK to cause various problems. And make sure you can use it well.
Longadder
Pending additions
Simple summary of Java visibility