Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Using 'volatile'  RSS feed

 
Aditya Jha
Ranch Hand
Posts: 227
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

Following are two code-pieces my questions are based upon:

1st code-piece:




2nd code-piece:



We can safely assume that the accessor and mutator methods are the simplest they can be, and perform exactly as above (and nothing else).

I have a few related questions:

1) What is the difference in behaviour of the two code-pieces mentioned above?
2) What if the value is not a primitive but an object-reference?
 
Henry Wong
author
Sheriff
Posts: 22832
119
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a few related questions:

1) What is the difference in behaviour of the two code-pieces mentioned above?
2) What if the value is not a primitive but an object-reference?


Functionally, there is no difference between the two code examples. This is because the two operations that you used (set and get) are atomic. If you created a new function like ...



Then the synchronized version still works -- but the volatile version will not work because the post increment operator is not atomic.

As for object references, setting and getting them are also atomic.

Henry
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is one difference: the synchronized version will block if another thread holds a reference to the instance you're trying to access. If for some reason the other thread does not give up the reference, you can block forever. Admittedly in the code shown there's no apparent reason for another thread to do this, but it's possible.

Also, if you consider other primitive reference types instead of int: prior to JDK 1.5, there was a long-standing bug where some JDKs did not enforce volatile correctly for long variables. That's not an issue now, but if you do use an older JDK, it might help to be aware of that.
 
Aditya Jha
Ranch Hand
Posts: 227
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot! I knew I could get more than I bargain for in JavaRanch.
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Re : volatile object reference bit

Also on earlier JDK's (pre 1.5 ???) / memory models, wasn't there an issue in that if you had a volatile reference to an object accessing it did not necessarily flush non synchronized writes on the object itself i.e. you could see the correct reference / object but not necessarily the updated fields of the object (i.e. non synchronized writes wre not guaranteed to be visible relative to the volatile access), where as the synchronized version would always work ?

I'm having difficulty pinning down exactly what bits of the memory model were confirmed when i.e. some changes happened 1.4 to 1.5 was this one of them or was it way earlier.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chris - yes, prior to JDK 5 volatile was only guaranteed (errr, supposedly guaranteed) to apply to access to the volatile field itself. Now it's been strengthened so that it effectively creates a memory flush much like synchronization does. This is discussed in the Java memory model FAQ.
[ December 12, 2006: Message edited by: Jim Yingst ]
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is no difference between the two. Even a multiple op type such as 'long' will show no difference.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sigh. I guess that means you still haven't tried running AtomicLong.java for yourself, using JDK 1.3 or earlier. Yes, according to the specs, volatile long should work - but for many years, it didn't. This is easy to try for yourself, using AtomicLong.java from Bill Pugh's Java memory model resources. Additionally, it's clear that when you say "There is no difference between the two", you haven't actually read the other comments here closely enough to address the issues we've been talking about in any meaningful way. I know you're much smarter than that. Why bother posting if you're not following the conversation?
 
Aditya Jha
Ranch Hand
Posts: 227
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, so if I'm sure I'm going to use JDK 5 (or later), is one of the two (synch methods or volatile properties) ways more efficient than the other?

I'm write a code-generator for generating boiler-plate code for my project. Few of the generated classes are going to be value-objects (something like I explained in first post). I want these classes to generate based upon some efficient model. And, when I think of costly call to synch methods, I tend to prefer the volatile properties approach. Although, a gut feeling tells me that even volatile should be costly in terms of efficiency as it is achieving the same effect.

Thanks to each and every one of you for giving this small topic an informative attention.
[ December 17, 2006: Message edited by: Aditya N Jha ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The cost of synchronization has decreased considerably since the earliest versions of Java. Many people think it's a lot more costly than it actually i now. I recommend you should not assume that "costly synchronization" will be a problem unless you can measure it. Volatile can be faster, particularly if most of the accesses will be simple gets or sets. However you may also want to try the new java.util.concurrent.atomic.* classes for simple volatile-like behavior, or the new java.util.concurrent.locks.* classes for more sophisticated to synchronization. However I don't really know which of these are fastest. I will guess that the atomic classes are very close to volatile, while lock and sync are a little slower - but probably not too much slower, and of course locks and sync can provide more complete protection, as well. Don't worry too much about what's fastest; instead, focus on what kind of protection you really need.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!