如果直接从内存中读取易失性字段,那么非易失性字段从哪里读取?
If volatile fields are read directly from memory, where are non-volatile fields read from?
我最近在阅读可变字段是线程安全的,因为
When we use volatile keyword with a variable, all the threads read
its value directly from the memory and don’t cache it
所以我想知道,对于非易失性字段,线程将从哪里读取它的值?我以为一切都存储在内存中。
你引用的说法是一种误解。
我推荐以下文章:https://software.rajivprab.com/2018/04/29/myths-programmers-believe-about-cpu-caches/
if volatile variables were truly written/read from main-memory every single time, they would be horrendously slow – main-memory references are 200x slower than L1 cache references. In reality, volatile-reads (in Java) can often be just as cheap as a L1 cache reference, putting to rest the notion that volatile forces reads/writes all the way to main memory. If you’ve been avoiding the use of volatiles because of performance concerns, you might have been a victim of the above misconceptions.
每个线程都有一个主存的Cache。
A field may be declared volatile, in which case the Java Memory Model
ensures that all threads see a consistent value for the variable
例如,我们有这个非线程安全的静态计数器
static int counter = 0;
如果两个线程读写这个变量就会像这样
Main memory - > static int counter
T1-> Cache of the Main Memory. Reads/Writes directly from Cache
T2-> Cache of the Main Memory. Reads/Writes directly from Cache
所以读写的时候会不一致
static volatile int counter = 0;
Main Memory - > static int counter;
T1 - > Read and Writes directly from the memory
T2 - > Read and Writes directly from the memory
我希望我能给你一个简单的总结。因为你将需要检查更多关于并发和Atomic Access变量的并发
在 Java Docs
中查看更多信息
处理器上的 core/thread 可以获取非 volatile
变量的副本并将其放置在自己的缓存中(不是主内存)。此缓存值得到更新,但主内存版本不会更新,直到线程认为是时候刷新该值。
如果另一个 core/thread 试图访问主内存中的值,它可能会在不知不觉中找到过时的值。
volatile 修饰符意味着变量数据在每次更改时都会在主内存中保持最新,因此在另一个线程需要时始终准备就绪access/edit。
我最近在阅读可变字段是线程安全的,因为
When we use volatile keyword with a variable, all the threads read its value directly from the memory and don’t cache it
所以我想知道,对于非易失性字段,线程将从哪里读取它的值?我以为一切都存储在内存中。
你引用的说法是一种误解。 我推荐以下文章:https://software.rajivprab.com/2018/04/29/myths-programmers-believe-about-cpu-caches/
if volatile variables were truly written/read from main-memory every single time, they would be horrendously slow – main-memory references are 200x slower than L1 cache references. In reality, volatile-reads (in Java) can often be just as cheap as a L1 cache reference, putting to rest the notion that volatile forces reads/writes all the way to main memory. If you’ve been avoiding the use of volatiles because of performance concerns, you might have been a victim of the above misconceptions.
每个线程都有一个主存的Cache。
A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable
例如,我们有这个非线程安全的静态计数器
static int counter = 0;
如果两个线程读写这个变量就会像这样
Main memory - > static int counter
T1-> Cache of the Main Memory. Reads/Writes directly from Cache
T2-> Cache of the Main Memory. Reads/Writes directly from Cache
所以读写的时候会不一致
static volatile int counter = 0;
Main Memory - > static int counter;
T1 - > Read and Writes directly from the memory
T2 - > Read and Writes directly from the memory
我希望我能给你一个简单的总结。因为你将需要检查更多关于并发和Atomic Access变量的并发 在 Java Docs
中查看更多信息处理器上的 core/thread 可以获取非 volatile
变量的副本并将其放置在自己的缓存中(不是主内存)。此缓存值得到更新,但主内存版本不会更新,直到线程认为是时候刷新该值。
如果另一个 core/thread 试图访问主内存中的值,它可能会在不知不觉中找到过时的值。
volatile 修饰符意味着变量数据在每次更改时都会在主内存中保持最新,因此在另一个线程需要时始终准备就绪access/edit。