Volatile array and Wait

classic Classic list List threaded Threaded
30 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Volatile array and Wait

Vijay-10
Question 1)
I have an array e.g.
    volatile long[] a1 = new long[100];
 
Now, is the object a1 volatile or every element of array a1 is volatile or both?
i.e. Is the value we assign to a1 volatile or every long value in the array volatile or both of the previous options are true?
 
Question 2)
When we come out of wait state, is it the same thing as entering a synchronized block? Will all the variables be taken from RAM again instead of from the register buffer?
 
Thanks for you help. This is very helpful mailing list.
Vijay.

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Jeremy Manson
Vijay wrote:
> Question 1) I have an array e.g. volatile long[] a1 = new long[100];
>
> Now, is the object a1 volatile or every element of array a1 is
> volatile or both?

The reference is volatile; the elements of the array are not.  Writes to
a1 will be volatile; writes to elements of a1 (a1[0], a1[1]...) will not.


> Question 2) When we come out of wait state, is it the same thing as
> entering a synchronized block? Will all the variables be taken from
> RAM again instead of from the register buffer?

When you wake from wait(), you must reacquire the lock before
proceeding; it therefore has the same semantics as a lock acquisition.

It is a little dangerous to think of these semantics in terms of main
memory and buffers, for reasons that have been discussed in detail on
this list.

Hope that helps!

                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Volatile array and Wait

Inanc Gumus
In reply to this post by Vijay-10
So, how to make inter array elements volatile?

-----Original Message-----
From: Jeremy Manson [mailto:[hidden email]]
Sent: Tuesday, October 18, 2005 7:30 AM
To: Vijay
Cc: [hidden email]
Subject: Re: [concurrency-interest] Volatile array and Wait

Vijay wrote:
> Question 1) I have an array e.g. volatile long[] a1 = new long[100];
>
> Now, is the object a1 volatile or every element of array a1 is
> volatile or both?

The reference is volatile; the elements of the array are not.  Writes to
a1 will be volatile; writes to elements of a1 (a1[0], a1[1]...) will
not.


> Question 2) When we come out of wait state, is it the same thing as
> entering a synchronized block? Will all the variables be taken from
> RAM again instead of from the register buffer?

When you wake from wait(), you must reacquire the lock before
proceeding; it therefore has the same semantics as a lock acquisition.

It is a little dangerous to think of these semantics in terms of main
memory and buffers, for reasons that have been discussed in detail on
this list.

Hope that helps!

                                        Jeremy


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Jeremy Manson
Inanc Gumus wrote:
> So, how to make inter array elements volatile?
>

There is no way to do this directly.  The simplest option is probably to
use AtomicReferenceArray, AtomicIntegerArray or AtomicLongArray.

Another option is to have an extra volatile dummy field associated with
the array.  After each write to an array element, write to the dummy
field (it doesn't matter what value is written).  Before each read of an
array element, read the dummy field (and discard the value).

A third option is to use indirection.  That is to say, you could create
an array of references to:

      class VolatileRef {
        public volatile Object ref = null;
     }


A fourth option is to use locking instead.

                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Volatile array and Wait

David Holmes
In reply to this post by Inanc Gumus
Inanc  Gumus writes:
>
> So, how to make inter array elements volatile?

There is no way to make plain array elements volatile (or final).

As an alternative, for some cases, you can use the array classes from
java.util.concurrent.atomic, eg. AtomicIntegerArray.

David Holmes

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Volatile array and Wait

Shaffer, Darron
In reply to this post by Vijay-10
The second option can use the volatile reference to the array as the
"dummy".

So given:

  volatile Object[] b = new Object[50];

reading looks like this:

   Object x = b[25];  // Volatile read must occur first, to find the
array.

writing looks like this:

   b[22] = x; Object dummy = b;  // Must have trailing volatile read.

If you do this, be sure and comment it well enough that a
junior/maintenance programmer doesn't decide that volatile applies to
the entire array.
 

-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Jeremy
Manson
Sent: Wednesday, October 19, 2005 9:40 AM
To: Inanc Gumus
Cc: Vijay; [hidden email]
Subject: Re: [concurrency-interest] Volatile array and Wait

Inanc Gumus wrote:
> So, how to make inter array elements volatile?
>

There is no way to do this directly.  The simplest option is probably to

use AtomicReferenceArray, AtomicIntegerArray or AtomicLongArray.

Another option is to have an extra volatile dummy field associated with
the array.  After each write to an array element, write to the dummy
field (it doesn't matter what value is written).  Before each read of an

array element, read the dummy field (and discard the value).

A third option is to use indirection.  That is to say, you could create
an array of references to:

      class VolatileRef {
        public volatile Object ref = null;
     }


A fourth option is to use locking instead.

                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Jeremy Manson
Shaffer, Darron wrote:

> The second option can use the volatile reference to the array as the
> "dummy".
>
> So given:
>
>   volatile Object[] b = new Object[50];
>
> reading looks like this:
>
>    Object x = b[25];  // Volatile read must occur first, to find the
> array.
>
> writing looks like this:
>
>    b[22] = x; Object dummy = b;  // Must have trailing volatile read.
>
> If you do this, be sure and comment it well enough that a
> junior/maintenance programmer doesn't decide that volatile applies to
> the entire array.


This won't work.  We should remind ourselves that it is important to be
very careful when trying to use volatile for patching up our code.  It
is really difficult to remember all of the rules, and to reason about
them correctly.

In this case, you have to think carefully about the "acquire" and
"release" semantics of volatiles.  A read performs an "acquire", and a
write performs a "release".  When you are writing to memory, you have to
perform a release.  So, in this case:

>> writing looks like this:
>>
>>    b[22] = x; Object dummy = b;  // Must have trailing volatile read.

you need a write to a volatile field, not a read of one.  It should look
like this:

Write:
b[22] = x;
b = b;

Or, slightly better, keep the value of the field called b in a local
variable:

Write:
int [] arr = b;
arr[22] = x;
b = arr;

IMPORTANT NOTE:

In general, you have to be very careful about using this.  I would
suspect that in nine cases out of ten, it will not do what you want it
to do.  For example, if you were trying to use this for a singleton, it
would NOT be correct:

Bad Writer Thread:
b[22] = new SingletonObject();
b = b;

Bad Reader Thread:
SingletonObject so = b[22];
so.doThings();

You could easily imagine the reader thread being scheduled between the
two statements of the writer thread.  Guess what?  In that case, you
don't see the effects of the volatile write.

                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Volatile array and Wait

David Holmes
In reply to this post by Shaffer, Darron
> Shaffer, Darron writes:
> The second option can use the volatile reference to the array as the
> "dummy".
>
> So given:
>
>   volatile Object[] b = new Object[50];
>
> reading looks like this:
>
>    Object x = b[25];  // Volatile read must occur first, to find the
> array.
>
> writing looks like this:
>
>    b[22] = x; Object dummy = b;  // Must have trailing volatile read.

No you need a volatile *write* to happen-before the volatile read. So you
would need to do:

     b[22] = x;  // write normal data
     b = b;      // volatile write

but this is not sufficient to guarantee that an element read sees the most
recent value, as the read could occur after the write to the element but
before the write to the array reference. Of course the program can't
distinguish this case from the case where the read of the element happens
before the write of the element.

David Holmes

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Jeremy Manson
In reply to this post by Jeremy Manson
Chris Purcell wrote:

>> Write:
>> b[22] = x;
>> b = b;
>
>
> Umm, shouldn't that be
>
> b = b;
> b[22] = x;
>
> ?
>
> After all, there's not use in publishing preceding writes *after* the
> lock's already released.
>

Nope.  The rule of thumb is that the release has to happen after you
perform the writes you want to publish.  The acquire has to happen
before you read the writes that have been published.

In this case, the write "b = b" is the release, and so must occur after
the write "b[22] = x", which is the write we wish to publish.

Also, bear in mind that there is no lock in this case.  This is part of
what makes it extremely difficult to analyze, and why people should
probably avoid it where possible.

                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Chris Purcell
> In this case, the write "b = b" is the release, and so must occur
> after the write "b[22] = x", which is the write we wish to publish.

Actually, b[22] = x is supposed to have release semantics, so every
preceding write must be made visible before it commits.

Chris

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Chris Purcell
In reply to this post by Jeremy Manson
Actually, that's probably my mistake. Apologies. Excuse me while I go
absorb the Java Memory Model again...

Chris

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Jeremy Manson
In reply to this post by Chris Purcell
Chris Purcell wrote:
>> In this case, the write "b = b" is the release, and so must occur
>> after the write "b[22] = x", which is the write we wish to publish.
>
>
> Actually, b[22] = x is supposed to have release semantics, so every
> preceding write must be made visible before it commits.
>
> Chris


This is exactly my point.  b[22] = x *doesn't* have release semantics.
It looks like this:

int [] a = b; // volatile read
a[22] = x; // array write

There is no release in there.  That's why you need the write "b = b",
which looks like this:

int [] a = b; // volatile read
b = a;  // volatile write

It is the volatile write that matters.

Like I said, it is hard to analyze this stuff.

                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Chris Purcell
Okay, I've thought this out a bit. My analysis follows.

1) A volatile write should have the same semantics as a monitor release
2) A volatile read should have the same semantics as a monitor acquire

A monitor release ensures all preceding writes are visible before it
commits. A monitor acquire prevents subsequent read operations from
passing across it. These give the appearance of sequential execution of
critical sections.

We wish to attach release semantics to our write to b[22]. Any
preceding writes must be visible to any reader who subsequently
performs an acquire.

If b[22] is *followed* by a volatile write/monitor release, there is a
period of time in which concurrent updates may see the new value of
b[22] but not any preceding writes despite performing an acquire in
between: namely, the time between the write to b[22] committing and the
release barrier.

Unfortunately, if the write to b[22] is *preceded* by a volatile
write/monitor release, the write to b[22] can be moved before the
release barrier (either by compiler or hardware) since it is not itself
volatile; once again there is a period of time in which concurrent
updates may see the new value of b[22] then do an acquire, yet still
not see any preceding writes, namely the time between the write to
b[22] committing and the release barrier.

However, if one could precede the write to b[22] with a release barrier
then a subsequent volatile read of a value on which the write operation
is dependent, then the write can no longer be reordered before the
barrier. The read of b should be sufficient for this.

Hence the correct code is:

b = b; // Release barrier
b[22] = x; // Subsequent acquire barrier followed by dependent write

as I suggested.

Attaching a monitor acquire to the read of b[22] is more problematic.
The acquire barrier must occur *after* the read of b[22] to prevent
subsequent reads from being reordered incorrectly. To do this, one must
make the acquire barrier *dependent* on the read of b[22], or risk them
being reordered. In assembler, this would be trivial, as one could fake
a volatile read that was dependent on the value of b[22]. I'm not clear
how to do this reliably in Java, as fake dependencies risk being
optimised away. The following might work, but might not:

x = b[22];
if (x < 1000)
    temp = b;
else
    temp = some_other_volatile;

In conclusion, don't try and emulate volatility.

Cheers,
Chris

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Jeremy Manson
Chris Purcell wrote:
> Okay, I've thought this out a bit. My analysis follows.

Hmm...  What we have here is a situation where I pointed out the problem
you bring up, and then you suggested a fix, and I completely missed that
you were pointing out a fix.

My mistake.  Sorry.

                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Chris Purcell
In reply to this post by Jeremy Manson
> Also, bear in mind that there is no lock in this case.  This is part
> of what makes it extremely difficult to analyze, and why people should
> probably avoid it where possible.

Amen to that ;)

Chris

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Chris Purcell
In reply to this post by Chris Purcell
> The following might work, but might not:
>
> x = b[22];
> if (x < 1000)
>    temp = b;
> else
>    temp = some_other_volatile;

Hmmm. Looking at this again, it's pretty unlikely that it will *ever*
work, as it's very easy to reorder reads across ifs. We want some way
of making the address of the volatile we are reading from unpredictably
determined by the value we read from b[22]. That means pointer
arithmetic. Unfortunately, the only way of doing that (that I know of)
in Java would look like:

     x = b[22]
     temp = a_volatile_array[x % 3]

which of course needs ... an array of volatile elements! Nice catch-22.

Cheers,
Chris

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Volatile array and Wait

Boehm, Hans
In reply to this post by Vijay-10
I agree with Chris' later posting.  And interestingly, that works only
because Java totally orders synchronization operations (at the cost of
making volatile writes relatively expensive).

Another way to look at this is that for any synchronization free
statements X and Y:

X; dummy = v; Y;

can be transformed to

dummy = v; X; Y;

i.e. the compiler can safely move the volatile load to the beginning of
the synchronization-free block (or equivalently move the preceding
synchronization-free operations past the acquire operation).

In this particular case, this means that that dummy = b can effectively
moved to just after the read of b in the computation of b[22], and is
thus effectively a no-op.

Hans

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf
> Of Shaffer, Darron
> Sent: Wednesday, October 19, 2005 9:08 AM
> To: Jeremy Manson; Inanc Gumus
> Cc: Vijay; [hidden email]
> Subject: RE: [concurrency-interest] Volatile array and Wait
>
>
> The second option can use the volatile reference to the array
> as the "dummy".
>
> So given:
>
>   volatile Object[] b = new Object[50];
>
> reading looks like this:
>
>    Object x = b[25];  // Volatile read must occur first, to
> find the array.
>
> writing looks like this:
>
>    b[22] = x; Object dummy = b;  // Must have trailing volatile read.
>
> If you do this, be sure and comment it well enough that a
> junior/maintenance programmer doesn't decide that volatile
> applies to the entire array.
>  
>
> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf
> Of Jeremy Manson
> Sent: Wednesday, October 19, 2005 9:40 AM
> To: Inanc Gumus
> Cc: Vijay; [hidden email]
> Subject: Re: [concurrency-interest] Volatile array and Wait
>
> Inanc Gumus wrote:
> > So, how to make inter array elements volatile?
> >
>
> There is no way to do this directly.  The simplest option is
> probably to
>
> use AtomicReferenceArray, AtomicIntegerArray or AtomicLongArray.
>
> Another option is to have an extra volatile dummy field
> associated with
> the array.  After each write to an array element, write to the dummy
> field (it doesn't matter what value is written).  Before each
> read of an
>
> array element, read the dummy field (and discard the value).
>
> A third option is to use indirection.  That is to say, you
> could create
> an array of references to:
>
>       class VolatileRef {
>         public volatile Object ref = null;
>      }
>
>
> A fourth option is to use locking instead.
>
> Jeremy
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Volatile array and Wait

Jeremy Manson
In reply to this post by Jeremy Manson
Jeremy Manson wrote:

> Chris Purcell wrote:
>
>> Okay, I've thought this out a bit. My analysis follows.
>
>
> Hmm...  What we have here is a situation where I pointed out the problem
> you bring up, and then you suggested a fix, and I completely missed that
> you were pointing out a fix.
>
> My mistake.  Sorry.
>

There is a little confusion about this.  I didn't realize that the
problem that Chris was fixing was this one I brought up:

 > In general, you have to be very careful about using this.  I would
 > suspect that in nine cases out of ten, it will not do what you want
 > it to do.  For example, if you were trying to use this for a
 > singleton, it would NOT be correct:
 >
 > Bad Writer Thread:
 > b[22] = new SingletonObject();
 > b = b;
 >
 > Bad Reader Thread:
 > SingletonObject so = b[22];
 > so.doThings();
 >
 > You could easily imagine the reader thread being scheduled between
 > the two statements of the writer thread.  Guess what?  In that case,
 > you don't see the effects of the volatile write.

Chris's point was that by putting the b = b statement *before* the write
to b[22], thus:

1: SingletonObject so = new SingletonObject();
2: b = b;
3: b[22] = so;

then if the reader thread sees the SingletonObject reference, it is
guaranteed to see the fully constructed SingletonObject.

Of course, if we were to use this code, it would mean that no one is
actually guaranteed to see the write of the SingletonObject reference to
b[22].  This was my point.  If you want to guarantee *that*, you have to
do it this way:

1: SingletonObject so = new SingletonObject();
2: b = b;
3: b[22] = so;
4: b = b;

The volatile write on line 2 guarantees that *if* anyone sees the
SingletonObject reference, they will also see the correctly constructed
SingletonObject.  The volatile write on line 4 changes that *if* to a
*when*: it guarantees that other threads will actually see the reference.

Sorry about the crossed signals.  I hope that clears matters up, and is
a clear illustration to people why this stuff is hard.

                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Volatile array and Wait

David Holmes
In reply to this post by Chris Purcell
Chris Purcell writes:
> We wish to attach release semantics to our write to b[22]. Any
> preceding writes must be visible to any reader who subsequently
> performs an acquire.

What we want to do is try to ensure that the write of b[22] is visible to a
subsequent read of b[22] - which would happen if the array element itself
were considered volatile. We're not (or the original context wasn't) using
b[22] as a flag to indicate the "availability" of other data - it is b[22]'s
value that we are interested in.

> If b[22] is *followed* by a volatile write/monitor release, there is a
> period of time in which concurrent updates may see the new value of
> b[22] but not any preceding writes despite performing an acquire in
> between: namely, the time between the write to b[22] committing and the
> release barrier.

Correct. You might see the updated value of b[22] even if you don't see
other writes that occurred prior to writing to b[22].

You can also read b[22] after the last write to it, but before the volatile
write makes it visible. So in short there is no way to guarantee a read of
b[22] will see the latest value because there will always be a window
between the write and the "release" in which a read can sneak in.

You can't use volatiles to guarantee an update won't be seen, only to
guarantee that it will be. So if you want to ensure that a group of updates
are seen either entirely or not at all then you need to use locks to prevent
the values from being inspected.

> Unfortunately, if the write to b[22] is *preceded* by a volatile
> write/monitor release, the write to b[22] can be moved before the
> release barrier (either by compiler or hardware) since it is not itself
> volatile; once again there is a period of time in which concurrent
> updates may see the new value of b[22] then do an acquire, yet still
> not see any preceding writes, namely the time between the write to
> b[22] committing and the release barrier.

Preceding the write to b[22] with a volatile write doesn't achieve anything
with respect to the value of b[22]. You need to think about happens-before
rather than thinking about reordering.

> However, if one could precede the write to b[22] with a release barrier
> then a subsequent volatile read of a value on which the write operation
> is dependent, then the write can no longer be reordered before the
> barrier. The read of b should be sufficient for this.
>
> Hence the correct code is:
>
> b = b; // Release barrier
> b[22] = x; // Subsequent acquire barrier followed by dependent write
>
> as I suggested.

"correct" depends on what you think this is achieving. The read of b will
prevent the reordering of the write to b[22] with the write to b. So any
writes preceding the write to b will become visible. *BUT* the write to
b[22] itself is not guaranteed visible - which is what was wanted: the
effect of having volatile array elements.

Of course another point to take away from this is that an array of volatile
elements isn't that useful anyway.

David Holmes

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Volatile array and Wait

David Holmes
In reply to this post by Jeremy Manson
Ah I see where the signals are getting crossed. Thanks for clarifying that
Jeremy.

Sorry for the confusion Chris.

David Holmes

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]]On Behalf Of Jeremy
> Manson
> Sent: Thursday, 20 October 2005 4:08 AM
> To: Jeremy Manson
> Cc: [hidden email]
> Subject: Re: [concurrency-interest] Volatile array and Wait
>
>
> Jeremy Manson wrote:
> > Chris Purcell wrote:
> >
> >> Okay, I've thought this out a bit. My analysis follows.
> >
> >
> > Hmm...  What we have here is a situation where I pointed out
> the problem
> > you bring up, and then you suggested a fix, and I completely
> missed that
> > you were pointing out a fix.
> >
> > My mistake.  Sorry.
> >
>
> There is a little confusion about this.  I didn't realize that the
> problem that Chris was fixing was this one I brought up:
>
>  > In general, you have to be very careful about using this.  I would
>  > suspect that in nine cases out of ten, it will not do what you want
>  > it to do.  For example, if you were trying to use this for a
>  > singleton, it would NOT be correct:
>  >
>  > Bad Writer Thread:
>  > b[22] = new SingletonObject();
>  > b = b;
>  >
>  > Bad Reader Thread:
>  > SingletonObject so = b[22];
>  > so.doThings();
>  >
>  > You could easily imagine the reader thread being scheduled between
>  > the two statements of the writer thread.  Guess what?  In that case,
>  > you don't see the effects of the volatile write.
>
> Chris's point was that by putting the b = b statement *before* the write
> to b[22], thus:
>
> 1: SingletonObject so = new SingletonObject();
> 2: b = b;
> 3: b[22] = so;
>
> then if the reader thread sees the SingletonObject reference, it is
> guaranteed to see the fully constructed SingletonObject.
>
> Of course, if we were to use this code, it would mean that no one is
> actually guaranteed to see the write of the SingletonObject reference to
> b[22].  This was my point.  If you want to guarantee *that*, you have to
> do it this way:
>
> 1: SingletonObject so = new SingletonObject();
> 2: b = b;
> 3: b[22] = so;
> 4: b = b;
>
> The volatile write on line 2 guarantees that *if* anyone sees the
> SingletonObject reference, they will also see the correctly constructed
> SingletonObject.  The volatile write on line 4 changes that *if* to a
> *when*: it guarantees that other threads will actually see the reference.
>
> Sorry about the crossed signals.  I hope that clears matters up, and is
> a clear illustration to people why this stuff is hard.
>
> Jeremy
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
12