As I understand that in process context switching the OS 'backups' the 开发者_开发技巧registers and instruction pointer (also part of register).
But in case of switching among threads within a process will the OS take backup of the full register memory and stack?
The reason I ask this is to understand if the volatile keyword of Java is of any significance in case of single core processors.
if the volatile keyword of Java is of any significance in case of single core processors.
The optimization used by the jit compiler may cause unexpected behavior.
static boolean foo = true;
public void bar(){
while(foo){
//doSomething
//do not modify foo in here
}
}
this may be optimized, since foo is not changed within the loop.
public void bar(){
while(true){
//Now this loop never ends
//changes to foo are ignored
}
}
making foo
volatile
will tell the jit compiler that foo
can be changed by a different thread and access to it should not be optimized.
This is valid behavior since cross thread access is only guaranteed to work with
- volatile and synchronized keywords
- classes which state to be threadsafe (for example java.util.concurrent.*)
Update
The volatile keyword does not influence context switching itself, however it influences how reads and writes of variables are optimized. This not only influences the use of the cpu cache (important for multi-core systems) but also the optimizations used by the just in time compiler as seen above (important on all systems).
understand if the volatile keyword of Java is of any significance in case of single core processors.
This line of thinking is unwise. You should program in accordance with the (documented) definition of the API and the virtual machine. You should not rely on something (in this case, the effect of volatile
) having a particular effect or lack of effect that is not part of its documented definition. Even if experiment suggests it has particular behaviour in particular circumstances. Because it will bite you.
Thread switching indeed means storing away all the computation registers and all the stack, simply because each thread indeed has a separate memory stack.
The volatile
keyword is still important in multithreading, even in single core environments, due to the way the Java memory model works. volatile
variables are not stored in any type of cache or register, but rather always fetched from main memory, to ensure each thread always sees the most recent value of the variable.
Yes, even for single core processors, volatile
is still useful. It tells the compiler that the value needs to be reread from memory each time it's read (because another thread may be updating it), and not just be cached in a register.
Check out JSR 133, and in particular the section labelled "What does volatile do?"
Volatile fields are special fields which are used for communicating state between threads. Each read of a volatile will see the last write to that volatile by any thread; in effect, they are designated by the programmer as fields for which it is never acceptable to see a "stale" value as a result of caching or reordering.
It's a useful introduction and description of how volatile
works with the JVM memory model.
I know what volatile
does but I am trying to understand why is this necessary. Let me elaborate.
As mentioned by josefx above. If we have something like below:-
while(run) {
//do something but don't modify run
}
If some other thread turn run
to false
then the while-loop will never end. As mentioned by Yuval A before, during thread context switch the registers too are backed up. So I guess it works like this.
If any thread modifies the value of run
, the value will be modified in the register only. During thread context switch Java won't synchronize this register value with the copy in RAM if not explicitly marked as volatile
. This way each thread will work with its own version of run
. But this concept don't apply to non-primitives and primitives like integer etc. which won't fit as whole in the register, forcing them to be synchronized with the RAM copy.
精彩评论