is volatile of no use on x86 processors

2019-04-17 11:01发布

问题:

I read somewhere that x86 processors have cache coherency and can sync the value of fields across multiple cores anyway on each write.

Does that mean that we can code without using the 'volatile' keywoard in java if we plan on running only on x86 processors?

Update:

Ok assuming that we leave out the issue of instruction reordering, can we assume that the issue of an assignment to a non-volatile field not being visible across cores is not present on x86 processors?

回答1:

No -- the volatile keyword has more implications than just cache coherency; it also places restrictions on what the runtime can and can't do, like delaying constructor calls.



回答2:

About your update: No we can't. Other threads could just read stale values without the variable being updated. And another problem: The JVM is allowed to optimize code as long as it can guarantuee that the single threaded behavior is correct.

That means that something like:

public boolean var = true;
private void test() {
    while (var) {
       // do something without changing var
    }
}

can be optimized by the JIT to while(true) if it wants to!



回答3:

There is a big difference between can sync the value of fields and always syncs the value of fields. x86 can sync fields if you have volatile, otherwise it doesn't and shouldn't.

Note: volatile access can be 10-30x slower than non-volatile access which is a key reason it is not done all the time.

BTW: Do you know of any multi-core, plain x86 processors. I would have thought most were x64 with x86 support.



回答4:

There are very exact specifications on how the JVM should behave for volatile and if it choose to do that using cpu-specific instructions then good for you.

The only place where you should say "we know that on this platform the cpu behaves like.." is when linking in native code where it needs to conform to the cpu. In all other cases write to the specification.

Note that the volatile keyword is very important for writing robust code running on multiple cpu's each with their own cache, as it tells the JVM to disregard local cache and get the official value instead of a cached value from 5 minutes ago. You generally want that.



回答5:

a write in bytecode doesn't even have to cause a write in machine code. unless it's a volatile write.



回答6:

I can vouch for volatile having some use. I've been in the situation where one thread has 'null' for a variable and another has the proper value for the variable that was set in that thread. It's not fun to debug. Use volatile for all shared fields :)