开发者

Volatile member between multithreaded application in java

What happen if two threads try to access same volatile variable at same time. what type of lock in this开发者_如何学运维 case. Please help me to remove this doubt.


This probably will help you:

  • The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory"
  • Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.

We say "acts as though" in the second point, because to the programmer at least (and probably in most JVM implementations) there is no actual lock object involved.

Source: http://www.javamex.com/tutorials/synchronization_volatile.shtml


I have a short text snippet for you explaining volatile variables.

Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread.

Yet accessing a volatile variable performs no locking and so cannot cause the executing thread to block, making volatile variables a lighter-weight synchronization mechanism than synchronized.

Example:

When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after reading the volatile variable.


On a single-CPU machine there is no such thing as "at the same time" - the operating system (OS) schedules each thread to be executed for a short period of time, before moving onto the next thread.

On multi-CPU (SMP) machines, two CPUs can be executing code simultaneously, but the Java Language Specification (JLS) provides guarantees about volatile fields so you can still write correct multi-threaded code.

From the programmer's point of view, there's no lock involved when dealing with volatile fields. Ignoring the uninteresting case where both threads are reading the field (spoiler: they see the same value) we have two cases:

  1. one thread reads, the other updates: the reader will either see the old or the new value, depending on the order in which the two threads are scheduled by the OS
  2. both threads update: the field will end up holding the value of whichever thread was scheduled most recently

It's important to note that:

  • even if the field is of type long, occupying 8 bytes of memory, the JLS guarantees that, with volatile fields, readers will never see (for example) 4 bytes of the "old" value and 4 bytes of the "new" - it's all-or-nothing
  • all threads scheduled after the update will see the new value immediately

Neither of these are necessarily true for non-volatile fields.


Most variable writes are atomic anyway, but volatile will ensure that the value is written to the area of memory completely before another thread tries to access it, and also makes sure that threads do not cache the variable for speed (context switching can be expensive so the interpreter might assume some things to gain speed). If volatile is not specified, it can be the case that two different threads can have different values of the variable in question at any one time, which can seriously mess things up.

This is a good read: http://expertdevelopers.blogspot.com/2011/03/atomicity-thread-safety-in-java.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜