does volatile works on object reference

Y

yancheng.cheok

hi all,

i am a bit confused on the usage of volatile keyword. consider the
following statement

public class Me
{
public Me()
{
primitive = 0;
arraylist = new ArrayList(100);
}

volatile int primitive;
volatile ArrayList arraylist;
}



Says there are two Thread A and B, A modify primitive value to 100. B
tries to read primitive value. B will get the latest primiteve value
(100) since B is reading directly from true primitive memory location,
not its cache.
(Please correct me if the above statement is wrong)

For point object reference, A trying to change the object reference to
a new ArrayList(200). B tries to read point. B will get the latest
ArrayList(200) object since B is reading directly from true arraylist
object reference memory location, not its cache.
(Please correct me if the above statement is wrong)

However, how about the elements inside the arraylist itself? Says A
try to change the arraylist element by
arraylist.setElementAtLocation("new value", 37). When B tries to
access the arraylist element at 37th, will it read directly from the
true arraylist 37th element memory location, or there is a possibility
B will read from 37th element cache memory?

Hence, is it safe, that we declare a arraylist as volatile, and assume
that all threads is able to get its most updated "element value"?

Thank you very much!

cheok
 
G

Gordon Beaton

However, how about the elements inside the arraylist itself?
[...]

Hence, is it safe, that we declare a arraylist as volatile, and
assume that all threads is able to get its most updated "element
value"?

You can find some good papers on this topic here:
http://www.cs.umd.edu/~pugh/java/memoryModel/
http://gee.cs.oswego.edu/dl/cpj/jmm.html

The second of these (an excerpt from Doug Lea's Concurrent Programming
in Java, a book I highly recommend) includes the following text, which
provides a succinct answer to your question:

Declaring a reference field as volatile does not ensure visibility
of non-volatile fields that are accessed via this reference.

/gordon

--
 
T

Tom Hawtin

i am a bit confused on the usage of volatile keyword. [...]
volatile ArrayList arraylist;
For point object reference, A trying to change the object reference to
a new ArrayList(200). B tries to read point. B will get the latest
ArrayList(200) object since B is reading directly from true arraylist
object reference memory location, not its cache.

Cache isn't the only important thing. If you try to use it for
'motivation' you will be led to incorrect conclusions. A more important
factor is compiler optimisations. Compilers do *really* odd and
unexpected things, so stick to Chapter 17 of JLS 3.
However, how about the elements inside the arraylist itself? Says A
try to change the arraylist element by
arraylist.setElementAtLocation("new value", 37). When B tries to
^list.set(37, "new value") ?
access the arraylist element at 37th, will it read directly from the
true arraylist 37th element memory location, or there is a possibility
B will read from 37th element cache memory?

You need to make assumptions about the implementation of ArrayList.
While they might be reasonable assumptions here, implementations in
general may well not do what you expect. There is an example in JBoss
where a HashMap used for logging (and therefore correctness not
necessarily that important) caused an infinite loop due to being used
concurrently.

However, for current versions of Java accessing a volatile affects
memory other than just the field declared volatile (except if you use
the weak/lazy methods in java.util.concurrent.atomic). If you write to
some fields then write to any volatile, and then in another thread read
*the same* volatile then read the fields, you will get the 'correct' answer.

However, if you just read the volatile field, nothing much is guaranteed.
Hence, is it safe, that we declare a arraylist as volatile, and assume
that all threads is able to get its most updated "element value"?

As long as you make some reasonable assumptions about ArrayList, you can
ensure you get updated values by inserting a write to the volatile field
after updating the element values:

public void set(int index, String value) {
List list = this.list();
list.set(index, value);
this.list = list; // <- actually important
}

However, you cannot change the ArrayList structurally and (always) get
away with it. Adding an element may cause the backing array to be
replaced in a non-thread-safe manner.

One approach is to copy the entire array before making a change (and
making sure it is updated atomically). However, if you are going to use
that you might as well just use
java.util.concurrent.CopyOnWriteArraylist (on the JSR166 backport for
1.4). Copy-on-read is a similar technique.

Anyway, for real code you are much better off using standard collections
that are thread safe. Low-level operations involving threads are very
difficult to get right and are usually done incorrectly.

Tom Hawtin
 
T

Tom Hawtin

Gordon said:
The second of these (an excerpt from Doug Lea's Concurrent Programming
in Java, a book I highly recommend) includes the following text, which
provides a succinct answer to your question:

Whilst that is a very good book, it is eight years old. The JMM has been
replaced since then, and the old one didn't work anyway.

More useful is Java Concurrency in Practice (Brian Goetz with others).
But I wouldn't want to see anyone writing production code with so much
as the synchronized keyword without having read both.
Declaring a reference field as volatile does not ensure visibility
of non-volatile fields that are accessed via this reference.

True in 1.3. But then, IIRC, in 1.3 volatile wasn't actually implemented
at all.

For implementations from 1.4 and the spec from 1.5, there is an
equivalent guarantee (but requires the volatile to be written to by the
thread that updates the indirect fields after updating).

Tom Hawtin
 

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,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top