Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Synchronization vs volatile.  RSS feed

 
Brendon McCullum
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm reading the volatile method use from this link : JavaTutorial
Here the author highlights a scenario where in two threads are accessing a shared resource, and performing write operations on it simultaneously, hence causing memory consistency errors across the threads.
That's where volatile comes into picture, and saves the day for us ensuring the writes operate in a happens-before relationship with the subsequent reads. The author lists out the use of volatile only in scenarios, where only
subsequent reads are permitted while a write. If this is the only use of volatile, this is ensured by synchronization, so what extra purpose does volatile serve. The point is that synchronization serves as a superset of volatile, hence is the only benefit in using volatile is to reduce the unnecessary synchronization overhead? Please help.
 
Joe Bishara
Ranch Hand
Posts: 175
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think you answered your question when you wrote "hence is the only benefit in using volatile is to reduce the unnecessary synchronization overhead?"

However, according to this article, when used wrongly, volatile may have a higher overhead than synchronized.
 
Henry Wong
author
Sheriff
Posts: 23275
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

To further elaborate this, the volatile variable is used as the basis for the atomic classes -- which interestingly, adds extra functionality while still remaining a lock free implementation.

On first glance, the atomic variables doesn't seem like much, but (1) it is lock free, meaning no synchronization, and (2) it implements the compare and set functionality, with is the basis needed to do optimistic locking.


So, one feature implements the mutually exclusive lock; the other feature is the basis for the application to do optimistic locking.

Henry
 
Martin Vajsar
Sheriff
Posts: 3752
62
Chrome Netbeans IDE Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:To further elaborate this, the volatile variable is used as the basis for the atomic classes...

Actually, atomic classes depend on the Unsafe class (which seems to be platform specific) to do its atomic magic. I might be wrong, but, having seen the JDK source, I'd guess that the Unsafe class manipulates the values directly (via pointer), thus sidestepping the volatile mechanism completely. Assuming this is true, the volatile keyword is probably used just to make sure threads will always see the latest value when accessing the atomic instance value.
 
Brendon McCullum
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Henry, it's getting a bit confusing as I study it more. As I see this, volatile serves a useful purpose, only when the operations to the underlying variable are atomic. I referred to your reply on this thread : Javaranch. As you say here, that the assignment operation is also not atomic and the reader thread could read in the value before the writer thread. If that's the case, I guess none of the operations are atomic, and volatile won't serve any purpose. The only use that I understand is when there's a happens-before relationship in the access order of variables. If that's the case, it becomes kind of a sequential order, where a thread first updates a variable, writes the changes to main memory instead of cache, and then subsequently other threads read it.
Also, I'd be grateful if you could explain a bit about optimistic locking as you've mentioned in your post. I googled this, but found that it's related to Hibernate, J2EE rather than the core Java part on which I'm stressing. Thanks a lot.
 
Henry Wong
author
Sheriff
Posts: 23275
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Brendon McCullum wrote:@Henry, it's getting a bit confusing as I study it more. As I see this, volatile serves a useful purpose, only when the operations to the underlying variable are atomic. I referred to your reply on this thread : Javaranch. As you say here, that the assignment operation is also not atomic and the reader thread could read in the value before the writer thread. If that's the case, I guess none of the operations are atomic, and volatile won't serve any purpose. The only use that I understand is when there's a happens-before relationship in the access order of variables. If that's the case, it becomes kind of a sequential order, where a thread first updates a variable, writes the changes to main memory instead of cache, and then subsequently other threads read it.


Yea, you are going to have to point out where I said that an assignment (which I am assuming you mean set) operation is not atomic.. because that is not true.

Henry
 
Henry Wong
author
Sheriff
Posts: 23275
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Brendon McCullum wrote:
Also, I'd be grateful if you could explain a bit about optimistic locking as you've mentioned in your post. I googled this, but found that it's related to Hibernate, J2EE rather than the core Java part on which I'm stressing. Thanks a lot.


"Optimistic Locking" is kinda of a misnomer, because a correctly implemented algorithm should not have a lock at all. The idea is that you are going to be "optimistic" that you won't have a collision, and will not need to lock it to be thread safe. This issue, of course, is what happens when a collision happens? That the part that is complicated.

The algorithm can't exposed any interim variables that can affect other threads, the algorithm must post the result atomically *and* must be able to detect if another thread did it first (collision), and of course, it needs a plan when the collision happens.

Take this code that I wrote a few years ago ... It is a thread safe mutable big decimal implementation.

http://www.coderanch.com/t/566492/threads/java/AtomicBigDecimal-class-interesting-find

It is lock free, uses the compare and set mechanism to detect collisions, and the plan for collision is to try again. It is probably not very useful, but it can serve as an example.

Henry
 
Brendon McCullum
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Henry, please check below code:



Basically, here a new value is being assigned to count. But that's an assignment operation, right? If it's not, can you list out any use case where volatile is guaranteed to succeed, in other way anything that is inherently atomic without explicit synchronization. Meanwhile I'll check out optimistic locking as you listed out. Thanks.
 
Henry Wong
author
Sheriff
Posts: 23275
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Brendon McCullum wrote:
Basically, here a new value is being assigned to count. But that's an assignment operation, right? If it's not, can you list out any use case where volatile is guaranteed to succeed, in other way anything that is inherently atomic without explicit synchronization.


The assignment at line 5 is atomic.

The conditional check (read) at line 3 is also atomic.

What isn't atomic, is both the compare and set together -- meaning that it is possible to use the variable between the compare and set. This is why the atomic classes needed to implement the functionality natively.

Henry
 
Brendon McCullum
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Henry, please check following code:



Here, if I make the count variable as volatile, no extra synchronization or locks would be needed, right? I've removed the compare so it remains a single atomic operation now. What I understand that volatile is guaranteed to work in atomic operations (both for reads and writes), and in other cases, we can either use conventional synchronization (pessimistic locking), or maybe go for some other CAS implementing algorithms (as the Atomic classes in Java do, and the one you shared above). Please correct me in case I'm getting this wrong. Also, I appreciate your efforts for answering my queries. Thanks.
 
Henry Wong
author
Sheriff
Posts: 23275
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Brendon McCullum wrote:
Here, if I make the count variable as volatile, no extra synchronization or locks would be needed, right? I've removed the compare so it remains a single atomic operation now. What I understand that volatile is guaranteed to work in atomic operations (both for reads and writes), and in other cases, we can either use conventional synchronization (pessimistic locking), or maybe go for some other CAS implementing algorithms (as the Atomic classes in Java do, and the one you shared above). Please correct me in case I'm getting this wrong. Also, I appreciate your efforts for answering my queries. Thanks.


Correct. However, I would also add that you can't mix them. For example, you can't use volatile for simple sets and gets, *and* use synchronization for the other cases. If you have different codes (running in different threads) touching the same data, you have to be consistent on how you protect that data.

Henry
 
Brendon McCullum
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Henry, thanks, it's pretty clear now.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!