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

Volatile Object References?  RSS feed

 
Alan W. Smith
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a question about Object references and how they behave in a multi-threaded environment. Suppose I have the following class where one thread calls the constructor and another thread calls a(), is there a guarantee that the thread running a() always see the value of m_string as "hello"?



If not, can I use volatile like so to guarantee that the thread running a() will see "hello"?

 
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
Suppose I have the following class where one thread calls the constructor and another thread calls a()...


Well, this case is not possible. In order to call a non-static method, you need a reference to a object. Basically, you need to construct an object, pass it to another thread, so that the other thread can call it. By the time the other thread gets the object, it would have been already constructed.

Henry
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It used to be possible. I believe in 1.4 a form of this can happen as references to objects can be returned before the object is finished constructing. This was fixed with the new memory model.
 
Alan W. Smith
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How about for the following slightly different case? If a thread calls b() first, after that another thread calls a(), is that other thread guaranteed to see "hello"? I want to see whether I need to pay the cost of synchronizations for a() & b() to keep the class thread-safe, when it's merely doing a read/write of a variable 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
If a thread calls b() first, after that another thread calls a(), is that other thread guaranteed to see "hello"?


Since the variable is declared as volatile, yes. This other thread should immediately see the changes.

It used to be possible. I believe in 1.4 a form of this can happen as references to objects can be returned before the object is finished constructing. This was fixed with the new memory model.


While it may have been possible, I always thought it was theoretical. I have never actually seen/heard of a case where this actually happened. Regardless, in this example, the context switch to the other thread, so that it may call the method, would flush the memory.

Henry
[ February 24, 2007: Message edited by: Henry Wong ]
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Flushing memory and completing construction are not the same thing.
Yes I think it was theoretical and that is why they fixed it with a spec change as opposed to a JVM change

What your asking in your latest post Alan is rather odd. Technically, the answer is yes. But practically, what does it mean that one thread calls a method before another thread?? You have imposed no ordering in your code, so the calls can come in any order.

Is it possible for one thread to miss the update of this variable by another thread? I am not entirely sure. I think the memory model was changed to make it so that it is not possible for one thread to miss this update by another thread. But of course there is no guarantee that one thread runs before or after another thread. Also there is no guarantee that one thread is allowed to finish its update before its switched off.


While I think volatile will give the thread a desire to flush its data, I am not sure if that desire extends to the OS? I do not believe there is a command to flush data straight from thread working memory directly to process memory area. It must always first be transfered from working memory to thread local memory, then to general process memory area. I am not sure if the thread can be interrupted before it flushes thread local memory to process memory or not!? I know with synchronized, the thread will get its memory flushed when the barrier is encountered. I guess volatile will impose a barrier as well and force all variables to be flushed? I don't know anymore. I havent picked apart the new spec yet...
 
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
Flushing memory and completing construction are not the same thing.
Yes I think it was theoretical and that is why they fixed it with a spec change as opposed to a JVM change


Hmmm... Yea, I agree. Good Point.

Henry
 
Justin Chu
Ranch Hand
Posts: 209
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is it true that if access to a instance variable is synchronized, having a volatile modifier for the instance variable is pointless?

Is the following scenario a valid description of the volatile modifier?

In the following code:

Case of instVar being not volatile:
At point A, instVar may not be read as "something else" by other threads.
At point B, instVar is _guaranteed_ to be read as "something else"

Case of instVar being volatile:
Point A and B, instVar is guaranteed to be read as "something else"
[ March 01, 2007: Message edited by: Chu Tan ]
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have not used synchronized in your example so I wont speak to that. However, if instVar is not volatile there is no 'guarantee' that its changed value will be read. Just because the method ends does not mean the value gets updated in main memory.

In the case of volatile, since 1.5 I believe you are correct in that main memory will be updated after its change. I think with 1.5 volatile has become a sort of best case 'synchronization'. Which makes entirely more sense that in 1.4 where it was next to useless. This is different from its use in c and other languages where declaring a variable volatile can ensure your value gets set on some output immediately. In Java we dont interface with output ports directly. I suppose if you had some JNI code that monitored a variable it may have paid to make it volatile, or if you were using J2ME on some hardware. But anyway its different in 1.5.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!