Memory consistency error in multithreaded program?

K

Knute Johnson

Say I have a class that holds some data fields. I access an instance of
this class from two or more threads. In these threads I assign new
values to the fields of this class and I read some element values as
well. I know that I won't ever have simultaneous access of the elements
of the class. But since one thread may change the values of the
elements I need to prevent any memory inconsistencies. Can I do that by
making the reference to the class volatile? Or do I need to synchronize
all access to my data class?

Does making a reference variable volatile do the same thing as making a
long or a short volatile?

Thanks very much,
 
E

Eric Sosman

Knute said:
Say I have a class that holds some data fields. I access an instance of
this class from two or more threads. In these threads I assign new
values to the fields of this class and I read some element values as
well. I know that I won't ever have simultaneous access of the elements
of the class. But since one thread may change the values of the
elements I need to prevent any memory inconsistencies. Can I do that by
making the reference to the class volatile? Or do I need to synchronize
all access to my data class?

Does making a reference variable volatile do the same thing as making a
long or a short volatile?

You say you "know" there won't be simultaneous access, but
how did you get this knowledge? Unless they synchronize, I don't
see how you can draw conclusions about the rates of progress in
different execution threads.

As for volatile: The "volatility" is not transitive. The
only thing that is volatile is the volatile field itself; if the
volatile thing is an object reference, the object instance's
fields do not magically become volatile by contagion, as it were.
If you want the object's fields to be volatile, you must declare
them as such in the class definition.
 
M

Matt Humphrey

Knute Johnson said:
Say I have a class that holds some data fields. I access an instance of
this class from two or more threads. In these threads I assign new values
to the fields of this class and I read some element values as well. I
know that I won't ever have simultaneous access of the elements of the
class. But since one thread may change the values of the elements I need
to prevent any memory inconsistencies. Can I do that by making the
reference to the class volatile? Or do I need to synchronize all access
to my data class?

It depends on what you mean by memory inconsistencies because you've already
said that two threads will not access the object at the same time. You will
not get low-level (non-atomic variable assignment) inconsistencies and will
not need the volatile keyword. However, if your object is updated in
multiple steps (i.e. if it's a Person with setLastName, setFirstName) you
may still get inconsistencies in the overall object state, even though each
step completes without conflict. It would happen with this sequence:
(Thread 1 is assigning the name "B Jones" and thread 2 is assigning the name
"A Smith"

Thread-1 Thread-2
setLastName('Jones') ----
---- setLastName ('Smith')
---- setFirstName('A')
setFirstName('B') ----

The final resulting person name will be "B Smith" which is totally
incorrect. No amount of synchronization within the object itself will fix
this--you must have locking across the compound operation.

Cheers,
 
P

Patricia Shanahan

Knute said:
Say I have a class that holds some data fields. I access an instance of
this class from two or more threads. In these threads I assign new
values to the fields of this class and I read some element values as
well. I know that I won't ever have simultaneous access of the elements
of the class. But since one thread may change the values of the
elements I need to prevent any memory inconsistencies. Can I do that by
making the reference to the class volatile? Or do I need to synchronize
all access to my data class?

Making everything you access volatile may cause worse performance than
trivial synchronization. By "trivial synchronization" I mean
synchronization in which there is no contention because of whatever else
is sequencing these actions.

You need to ensure the "happens-before" relation between the operations
on the shared object, as defined in
http://java.sun.com/docs/books/jls/third_edition/html/memory.html#61803

Since you don't expect any contention, there is no reason to mess with
lots of little locks. Why not just synchronize the whole block of work?
Does making a reference variable volatile do the same thing as making a
long or a short volatile?

Yes and no. It does exactly the same in that accesses to the reference
itself are treated as volatile. It does not affect the treatment of
references to fields in the object referenced by it.

Patricia
 
K

Knute Johnson

Knute said:
Say I have a class that holds some data fields. I access an instance of
this class from two or more threads. In these threads I assign new
values to the fields of this class and I read some element values as
well. I know that I won't ever have simultaneous access of the elements
of the class. But since one thread may change the values of the
elements I need to prevent any memory inconsistencies. Can I do that by
making the reference to the class volatile? Or do I need to synchronize
all access to my data class?

Does making a reference variable volatile do the same thing as making a
long or a short volatile?

Thanks very much,

Thanks very much everybody.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top