简体   繁体   中英

Under what circumstances will OS/CPUs not yield eventual consistency in non-volatile Java variables in practice?

We're trying to avoid atomics and reads-to-memory whenever possible in our cloud service product. As a result, we're having a lively debate regarding in-practice eventual consistency (also referred to as eventual visibility) of static variables when Java is running on modern processors.

It is accepted that the Java language specification does not guarantee either cross-thread-update-visibility OR eventual-consistency for multithreaded changes to statically-scoped variables UNLESS they are defined as volatile. Basically, not using the volatile keyword means there are no guarantees about consistency. Use of volatile keyword ensures instruction ordering and immediate visibility/consistency of the variable's latest value across threads.

However, in practice , when modern commercial CPUs write to a static variable, they do queue a memory update hint of some form to the cache controller, which then eventually forces the memory location to update in cache across cores. And, unless the memory location being read is in a tight loop on a specific thread, normal CPU utilization on enterprise workloads does appear to eventually generate the required cache hints to generate consistency across threads for the non-volatile static variables in practice (barring compiler optimization edge cases that cause weird reordering issues).

As an example, if we have multiple Java threads reading a statically-shared variable with no volatile qualifier, with one thread generating very widely spaced writes to the variable (one every few hours), then Java test code consistently shows threads quickly picking up the value change regardless of not having the volatile qualifier. This is likely due to the underlying OS/CPU architectures invalidating the per-core cache.

So our question is this: Compiler reordering issues aside (eg termination conditions in loops), can anyone shed some light on when this OS/CPU not-guaranteed-but-there-in-practice eventual-consistency will not occur?

For example, are there actual Intel/AMD/ARM architectures or flavors of Linux that this not-guaranteed-but-there-in-practice eventual consistency will not occur on? Our tests indicate it always eventually generates consistency on MacOS Linux even without the volatile keyword.

Modern CPU have consistent memory model, so if variable is written to memory it will be visible (can be changed at any moment in the future, so don't rely on that).

Thing that will fail you in practice is JIT, it can decide never store variable in memory at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM