Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #11400 > unrolled thread
| Started by | "raphfrk@gmail.com" <raphfrk@gmail.com> |
|---|---|
| First post | 2012-01-17 04:04 -0800 |
| Last post | 2012-01-17 10:24 -0800 |
| Articles | 14 on this page of 74 — 9 participants |
Back to article view | Back to comp.lang.java.programmer
Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-17 04:04 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-17 08:17 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 08:50 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-17 09:00 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-17 08:54 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 11:24 -0800
Re: Volatile happens before question Patricia Shanahan <pats@acm.org> - 2012-01-17 14:49 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-17 15:49 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-17 17:14 -0800
Re: Volatile happens before question Patricia Shanahan <pats@acm.org> - 2012-01-17 18:17 -0800
Re: Volatile happens before question Joshua Maurice <joshuamaurice@gmail.com> - 2012-01-19 16:45 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-17 08:18 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 08:33 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-17 08:49 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-17 09:21 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 10:10 -0800
Re: Volatile happens before question Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2012-01-17 10:28 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 10:41 -0800
Re: Volatile happens before question Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2012-01-17 11:06 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 12:09 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 12:12 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-17 12:38 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 13:35 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 14:41 -0800
Re: Volatile happens before question Patricia Shanahan <pats@acm.org> - 2012-01-17 14:55 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 15:27 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-17 17:37 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-17 17:42 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-17 15:46 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-17 16:14 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-17 20:01 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-17 20:37 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-17 21:52 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-17 23:47 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-18 00:08 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-18 09:04 -0800
Re: Volatile happens before question Steven Simpson <ss@domain.invalid> - 2012-01-18 11:22 +0000
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-18 06:24 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-18 07:32 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-18 08:34 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-18 10:12 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-18 11:15 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-18 11:59 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-18 12:24 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-18 13:16 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-18 15:00 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-18 16:12 -0800
Re: Volatile happens before question Patricia Shanahan <pats@acm.org> - 2012-01-18 16:34 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-18 17:17 -0800
Re: Volatile happens before question Patricia Shanahan <pats@acm.org> - 2012-01-18 19:03 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-18 15:30 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-18 16:10 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-19 08:18 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-19 09:40 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-19 10:10 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-19 10:39 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-19 12:13 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-19 13:31 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-19 16:14 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-19 21:16 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-20 03:23 -0800
Re: Volatile happens before question "raphfrk@gmail.com" <raphfrk@gmail.com> - 2012-01-20 06:46 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-20 08:56 -0800
Re: Volatile happens before question Lew <noone@lewscanon.com> - 2012-01-20 11:12 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-18 17:06 -0800
Re: Volatile happens before question Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2012-01-19 12:46 -0800
Re: Volatile happens before question markspace <-@.> - 2012-01-19 13:38 -0800
Re: Volatile happens before question Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2012-01-18 07:32 -0800
Re: Volatile happens before question Lew <noone@lewscanon.com> - 2012-01-18 00:06 -0800
Re: Volatile happens before question Knute Johnson <nospam@knutejohnson.com> - 2012-01-18 09:23 -0800
Re: Volatile happens before question Joshua Maurice <joshuamaurice@gmail.com> - 2012-01-19 17:07 -0800
Re: Volatile happens before question Joshua Maurice <joshuamaurice@gmail.com> - 2012-01-19 17:12 -0800
Re: Volatile happens before question Joshua Maurice <joshuamaurice@gmail.com> - 2012-01-19 19:22 -0800
Re: Volatile happens before question Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2012-01-17 10:24 -0800
Page 4 of 4 — ← Prev page 1 2 3 [4]
| From | "raphfrk@gmail.com" <raphfrk@gmail.com> |
|---|---|
| Date | 2012-01-20 03:23 -0800 |
| Message-ID | <626c6bb6-103f-4b89-8484-316641c0476c@18g2000yqe.googlegroups.com> |
| In reply to | #11514 |
On Jan 20, 5:16 am, markspace <-@.> wrote:
> This can't synchronize, because even when the read of v does come after
> the write of v, b is still read before that, so it's value is really
> free to be anything.
The issue is that a read of the old value doesn't guarantee that no
update has happened.
From my example:
Thread 1 Thread 2
Writer Reader
writerCounter.get() // RA
map.get() // R-read
writerCounter.get() // RB
writeCounter.increment() // WA
map.put(); // W-write
writeCounter.increment() // WB
Even though WA happens after RB in the synchronization ordering, there
is no relationship between R-read and W-write. The reason is that WA
and RB have no happens-before relationship.
The map.put could be in progress while map.get() is in progress.
It would work if you change it to:
Thread 1 Thread 2
Writer Reader
writerCounter.get() // RA
map.get() // R-read
writerCounter.getAndAdd(0) // RB
writeCounter.increment() // WA
map.put(); // W-write
writeCounter.increment() // WB
The write component of RB then happens-before the read component of
WA.
Thus the ordering is
RA -> R-read -> RB -> WA -> W-write -> WB
Thus, R-read will be completed before W-write starts.
[toc] | [prev] | [next] | [standalone]
| From | "raphfrk@gmail.com" <raphfrk@gmail.com> |
|---|---|
| Date | 2012-01-20 06:46 -0800 |
| Message-ID | <87e5dd57-cccc-4f97-b0cb-246ed076ab6f@j15g2000yqb.googlegroups.com> |
| In reply to | #11518 |
On Jan 20, 11:23 am, "raph...@gmail.com" <raph...@gmail.com> wrote:
> It would work if you change it to:
> <remove>
>
An improved way of doing it was given on the concurrent-interest
mailing list.
Thread 1 Thread 2
Writer Reader
int seq = writerCounter.get() // RA
map.get() // R-read
boolean success =
writerCounter.compareAndSet(seq, seq) // RB
writeCounter.increment() // WA
map.put(); // W-write
writeCounter.increment() // WB
compareAndSet also counts as a read and a write.
[toc] | [prev] | [next] | [standalone]
| From | markspace <-@.> |
|---|---|
| Date | 2012-01-20 08:56 -0800 |
| Message-ID | <jfc6bc$569$1@dont-email.me> |
| In reply to | #11518 |
On 1/20/2012 3:23 AM, raphfrk@gmail.com wrote: > The issue is that a read of the old value doesn't guarantee that no > update has happened. ... > Even though WA happens after RB in the synchronization ordering, > there is no relationship between R-read and W-write. The reason is > that WA and RB have no happens-before relationship. I don't think this is quite correct. No update is in progress in your trace. What I think they're talking about is causality, or the idea that map.get() might see a write from the future. That is, a write from the map.put(). I don't see anywhere in the JLS where it says that reads can't be reordered across this type memory barrier. I'll have to dig out JCIP since at this point I think trying to read the math heavy sections of the JLS have defeated me. The read from the future thing kinda makes sense, since I don't recall anything that prevents it. Maybe there is though... Note I already mentioned this about 4 posts ago... ;-)
[toc] | [prev] | [next] | [standalone]
| From | Lew <noone@lewscanon.com> |
|---|---|
| Date | 2012-01-20 11:12 -0800 |
| Message-ID | <jfcea1$uue$1@news.albasani.net> |
| In reply to | #11524 |
markspace wrote:
> raphfrk@gmail.com wrote:
>> The issue is that a read of the old value doesn't guarantee that no
>> update has happened.
> ...
>> Even though WA happens after RB in the synchronization ordering,
>> there is no relationship between R-read and W-write. The reason is
>> that WA and RB have no happens-before relationship.
>
>
> I don't think this is quite correct. No update is in progress in your trace.
There is no happens-before between what raphfrk marked as "R-read" and
"W-write". He is quite correct.
> What I think they're talking about is causality, or the idea that map.get()
No, about visibility.
> might see a write from the future. That is, a write from the map.put(). I
> don't see anywhere in the JLS where it says that reads can't be reordered
> across this type memory barrier.
That's not different from what raphfrk said.
> I'll have to dig out JCIP since at this point I think trying to read the math
> heavy sections of the JLS have defeated me. The read from the future thing
> kinda makes sense, since I don't recall anything that prevents it. Maybe there
> is though...
>
> Note I already mentioned this about 4 posts ago... ;-)
When there are more than one read and more than one write, you have to look at
the entire picture. Many in this conversation have made the mistake of looking
at only the first of a series of reads or writes and trying to reason about
the visible value, while ignoring later, possibly reordered actions.
Bottom line - the read from thread 2 (T2) before the write to a volatile in T1
does not impose a happens-before ("/hb/" or "<") between those two actions.
Does not. All bets are off. Done.
If the T2 read follows a different T1 write with which there is a /hb/
relationship that's a red herring.
--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
[toc] | [prev] | [next] | [standalone]
| From | Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> |
|---|---|
| Date | 2012-01-18 17:06 -0800 |
| Message-ID | <t8vcjhazyvos$.2mmkolb78ch6.dlg@40tude.net> |
| In reply to | #11474 |
On Wed, 18 Jan 2012 11:59:39 -0800, markspace wrote: > [...] > The bit that confuses me is that he "protects" his map with a write counter: > > writeCounter.getAndIncrement(); > map.put(key, value); > writeCounter.getAndIncrement(); > > And then allows the reader(s) into the critical section whenever the > writeCounter is even (why not just decrement the counter after a write > access?). Decrementing the counter would prevent the reader from detecting that a write to the data structure had occurred while the reader was trying to retrieve the value. Now, that said...I retract my previous statement that the code is safe. The code ensures that the reader won't attempt to _start_ reading if a write is in progress. But there's nothing to prevent the writer from starting to write while a read is in progress. This could result in a corrupted read at best, and a program crash at worst (if the data structure winds up in an invalid intermediate state just at the wrong time). The reader can detect the corrupted read (because the counter has been incremented), but has nothing to protect itself from an exception. > while (((save = writeCounter.get()) & 1) == 1); > value = map.get(key); > > So if a reader starts "first" and passes the first test > (writeCounter==0), and then starts to access the map, and then a writer > comes in and also begins to access the map... yeah you have two threads > accessing the map at the same time. This doesn't seem to work at all. Agreed. Pete
[toc] | [prev] | [next] | [standalone]
| From | Daniel Pitts <newsgroup.nospam@virtualinfinity.net> |
|---|---|
| Date | 2012-01-19 12:46 -0800 |
| Message-ID | <li%Rq.1257$IK3.540@newsfe14.iad> |
| In reply to | #11474 |
On 1/18/12 11:59 AM, markspace wrote: > On 1/18/2012 11:15 AM, raphfrk@gmail.com wrote: >> On Jan 18, 6:12 pm, markspace<-@.> wrote: >>> Yeah, it's a trick. >> >> You mean yeah, it has the same problem, so won't work either? > > > Looking at his code a bit more carefully, I think it has problems, but > not the same one. I guess the extra variables in his code that you're > looking at are local variables. So those are safe, they don't figure > into multi-threading concerns. > > The bit that confuses me is that he "protects" his map with a write > counter: > > writeCounter.getAndIncrement(); > map.put(key, value); > writeCounter.getAndIncrement(); > > And then allows the reader(s) into the critical section whenever the > writeCounter is even (why not just decrement the counter after a write > access?). Because the reads need to be restarted if there has been any write. Therefore its not enough to protect with just an "is zero". > > while (((save = writeCounter.get()) & 1) == 1); > value = map.get(key); > > So if a reader starts "first" and passes the first test > (writeCounter==0), and then starts to access the map, and then a writer > comes in and also begins to access the map... yeah you have two threads > accessing the map at the same time. This doesn't seem to work at all. > That's why he has "save". If the write happens and then the read attempts to read, the read needs to retry. > (Hint: ConcurrentHashMap Agreed, if you need this behavior. On the other hand, if you are experimenting with concurrency code, rather than trying to write concurrent applications, then this thread is more useful than knowing about CHM. > > <http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html>)
[toc] | [prev] | [next] | [standalone]
| From | markspace <-@.> |
|---|---|
| Date | 2012-01-19 13:38 -0800 |
| Message-ID | <jfa2h2$q8l$1@dont-email.me> |
| In reply to | #11501 |
On 1/19/2012 12:46 PM, Daniel Pitts wrote: > On 1/18/12 11:59 AM, markspace wrote: >> (Hint: ConcurrentHashMap > Agreed, if you need this behavior. On the other hand, if you are > experimenting with concurrency code, rather than trying to write > concurrent applications, then this thread is more useful than knowing > about CHM. Yes, this thread is excellent for learning stuff and making me look stuff up and justify what I think I know about concurrency. However, I'd like to point out that M. Bartosz Milewski says that developing lock-free algorithms are the subject of P.h.D. dissertations that take years of peer review before they're finally deemed correct. There's no way I'd put any of the code on this thread into production! Please stick to the Java API for production code, that's stuff is already debugged! ;-) >> <http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html>) >> >
[toc] | [prev] | [next] | [standalone]
| From | Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> |
|---|---|
| Date | 2012-01-18 07:32 -0800 |
| Message-ID | <13sztp1wewbfj$.1ikg73x4wq7x9.dlg@40tude.net> |
| In reply to | #11457 |
On Wed, 18 Jan 2012 11:22:23 +0000, Steven Simpson wrote: > [...] > This time, 'volatile' does not guarantee anything for the write to 'b'. > It could be optimized to happen as early as t0, so we cannot assert that > thread 2 will always use the initial value of 'b'. > > So, 'volatile' does not prevent the write to 'b' from jumping back into > the past of the write to 'a'. That is a correct restatement of my understanding, yes.
[toc] | [prev] | [next] | [standalone]
| From | Lew <noone@lewscanon.com> |
|---|---|
| Date | 2012-01-18 00:06 -0800 |
| Message-ID | <jf5uh7$9vh$1@news.albasani.net> |
| In reply to | #11453 |
On 01/17/2012 09:52 PM, Knute Johnson wrote:
> Let's start over here:
>
> Thread 1
> int b = 0;
> volatile boolean a = false;
> ...
> ...
> a = true;
> b = 1;
>
> Thread 2
> int bStore = b;
> if (!a) {
> System.out.println("The value of b is " + bStore);
> }
>
> Will this always print either "The value of b is 0" or nothing.
>
> +++++++++++++++
>
> I'm not even sure what we are discussing any more so I will make a statement
> that I don't think can be false.
I'm going to go out on a limb here.
> If a is false at the if in thread 2 then b must be 0 in thread 2.
No. Thread 2 could observe the write 'b = 1;' prior to observing the write 'a
= true;'.
"observes" means "thread 2 observes from thread 1:".
«(observes 'a == false') implies (observes 'b = 0')».
This is clearly true because
'b = 0' /hb/ 'a = false' /hb/ if (!a) true
«(observes 'b = 1') implies (observes 'a = true')»
«(observes 'a = true') implies (observes 'b = 1')»
Neither is true. There is no /hb/ between the two writes. Thread 2 can observe
them in either order.
«(observes 'a == false') implies (!observes 'b = 1')».
There is no /hb/ between these two writes. Ergo thread 2 could view them in
either order.
> In thread 1, b = 0 happens before a = false happens before a = true happens
> before b = 1.
Yes, but thread 2 does not have this /hb/ order. There is no inter-thread /hb/
that orders the writes 'a = false;', 'a = true;' and 'b = 1;'. T2 can see 'b
= 1;' prior to either write to 'a'.
> In thread 2, bStore = b happens before the test of a. Therefore bStore must be
> 0 in the print statement if a is false.
No. T2 can observe 'b = 1;' because no promise or prevention applies to writes
that happen after the observed write to 'a'.
> And if a is true at the test in thread 2 then b could be either 0 or 1.
>
> Do we disagree on this?
There is no /hb/ among the writes to 'a' and the 'b = 1;' write that T2 can
observe. T2 can see consecutive writes of zero and one to 'b' before it sees
any of the writes to 'a', or it could never see the 'b = 1;' write, or
anything in between.
--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
[toc] | [prev] | [next] | [standalone]
| From | Knute Johnson <nospam@knutejohnson.com> |
|---|---|
| Date | 2012-01-18 09:23 -0800 |
| Message-ID | <jf6v5l$2h6$1@dont-email.me> |
| In reply to | #11455 |
On 1/18/2012 12:06 AM, Lew wrote:
> On 01/17/2012 09:52 PM, Knute Johnson wrote:
>> Let's start over here:
>>
>> Thread 1
>> int b = 0;
>> volatile boolean a = false;
>> ...
>> ...
>> a = true;
>> b = 1;
>>
>> Thread 2
>> int bStore = b;
>> if (!a) {
>> System.out.println("The value of b is " + bStore);
>> }
>>
>> Will this always print either "The value of b is 0" or nothing.
>>
>> +++++++++++++++
>>
>> I'm not even sure what we are discussing any more so I will make a
>> statement
>> that I don't think can be false.
>
> I'm going to go out on a limb here.
>
>> If a is false at the if in thread 2 then b must be 0 in thread 2.
>
> No. Thread 2 could observe the write 'b = 1;' prior to observing the
> write 'a = true;'.
>
> "observes" means "thread 2 observes from thread 1:".
>
> «(observes 'a == false') implies (observes 'b = 0')».
> This is clearly true because
> 'b = 0' /hb/ 'a = false' /hb/ if (!a) true
>
> «(observes 'b = 1') implies (observes 'a = true')»
> «(observes 'a = true') implies (observes 'b = 1')»
>
> Neither is true. There is no /hb/ between the two writes. Thread 2 can
> observe them in either order.
>
> «(observes 'a == false') implies (!observes 'b = 1')».
>
> There is no /hb/ between these two writes. Ergo thread 2 could view them
> in either order.
>
>> In thread 1, b = 0 happens before a = false happens before a = true
>> happens
>> before b = 1.
>
> Yes, but thread 2 does not have this /hb/ order. There is no
> inter-thread /hb/ that orders the writes 'a = false;', 'a = true;' and
> 'b = 1;'. T2 can see 'b = 1;' prior to either write to 'a'.
>
>> In thread 2, bStore = b happens before the test of a. Therefore bStore
>> must be
>> 0 in the print statement if a is false.
>
> No. T2 can observe 'b = 1;' because no promise or prevention applies to
> writes that happen after the observed write to 'a'.
>
>> And if a is true at the test in thread 2 then b could be either 0 or 1.
>>
>> Do we disagree on this?
>
> There is no /hb/ among the writes to 'a' and the 'b = 1;' write that T2
> can observe. T2 can see consecutive writes of zero and one to 'b' before
> it sees any of the writes to 'a', or it could never see the 'b = 1;'
> write, or anything in between.
>
I woke up at 5 this morning thinking about this and I think I agree with
you now. The more I think about this the less sense it makes. Or maybe
it's the less sense I make :-).
--
Knute Johnson
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2012-01-19 17:07 -0800 |
| Message-ID | <3affbf10-5b32-4be1-a46b-201b257b798c@n7g2000pbd.googlegroups.com> |
| In reply to | #11453 |
On Jan 17, 9:52 pm, Knute Johnson <nos...@knutejohnson.com> wrote:
> Let's start over here:
>
> Thread 1
> int b = 0;
> volatile boolean a = false;
> ...
> ...
> a = true;
> b = 1;
>
> Thread 2
> int bStore = b;
> if (!a) {
> System.out.println("The value of b is " + bStore);
>
> }
>
> Will this always print either "The value of b is 0" or nothing.
>
> +++++++++++++++
>
> I'm not even sure what we are discussing any more so I will make a
> statement that I don't think can be false.
Let's try it like this:
"[initial] a=false" < "[t1] a=true" < "[t1] b=1"
"[initial] b=0" < "[t1] a=true" < "[t1] b=1"
"[initial] a=false" < "[t2] bStore=b" < "[t2] test of a"
"[initial] b=0" < "[t2] bStore=b" < "[t2] test of a"
Let's consider the case that the volatile read "[t2] test of a" reads
the value of the volatile write "[t1] a=true". Then, according to the
rules for volatile, we can conclude:
"[initial] a=false" < "[t1] a=true" < "[t2] test of a"
We also know that "[t2] test of a" reads true.
On the other case, if the volatile read "[t2] test of a" does not read
the value of the volatile write "[t1] a=true", then we can conclude
nothing further about "happens-before" relationships. We do know that
"[t2] test of a" reads false.
> If a is false at the if in thread 2 then b must be 0 in thread 2.
You've lost me already. You cannot conclude that. There's no
transitivity to the above happens-before relationships that let you
conclude that. Specifically, you cannot conclude that:
"[t1] b=1" < "[t2] bStore=b"
and thus you have a non-volatile read and a non-volatile write that
are not ordered by happens-before, and thus you have a race condition,
and thus the read can read any write it wants (but not a "out of thin
air" value).
In short, The rule you need to know is: (Without race conditions) if a
volatile-read (acquire-read) reads the side effect, the value, of a
volatile-write (release-write), then all reads after the volatile-read
(acquire-read) see all writes before the volatile-write (release-
write) (or the reads read the values of later writes). (Of course, you
can strengthen my paraphrase, but it's a useful paraphrase.)
In your example, you have it backwards - a read X before an acquire-
read, and a write Y after a release-write. You can use the volatile
semantics to conclude anything about X and Y.
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2012-01-19 17:12 -0800 |
| Message-ID | <a8db1047-1d72-4777-9c1a-a781c84002fc@p3g2000pbb.googlegroups.com> |
| In reply to | #11509 |
On Jan 19, 5:07 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote: > On Jan 17, 9:52 pm, Knute Johnson <nos...@knutejohnson.com> wrote: > > If a is false at the if in thread 2 then b must be 0 in thread 2. > > You've lost me already. You cannot conclude that. There's no > transitivity to the above happens-before relationships that let you > conclude that. Specifically, you cannot conclude that: > "[t1] b=1" < "[t2] bStore=b" > and thus you have a non-volatile read and a non-volatile write that > are not ordered by happens-before, and thus you have a race condition, > and thus the read can read any write it wants (but not a "out of thin > air" value). Typo. If you want to argue that the read "[t2] bStore=b" must read 0, then you must argue that "[t2] bStore=b" < "[t1] b=1" which you cannot conclude either.
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2012-01-19 19:22 -0800 |
| Message-ID | <a2a42480-ca61-4b51-9b2f-d1f2a77e4cad@a8g2000pbi.googlegroups.com> |
| In reply to | #11509 |
On Jan 19, 5:07 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote: > In your example, you have it backwards - a read X before an acquire- > read, and a write Y after a release-write. You can use the volatile > semantics to conclude anything about X and Y. Ack. Typos abound. 'You **can't** use the volatile semantics to conclude anything about X and Y." Ugg. I did do a quick review. Apparently I need to reread my stuff better before hitting submit.
[toc] | [prev] | [next] | [standalone]
| From | Daniel Pitts <newsgroup.nospam@virtualinfinity.net> |
|---|---|
| Date | 2012-01-17 10:24 -0800 |
| Message-ID | <_1jRq.2103$d%2.551@newsfe07.iad> |
| In reply to | #11400 |
On 1/17/12 4:04 AM, raphfrk@gmail.com wrote:
> The spec says that all writes to volatiles can be considered to happen
> before all subsequent reads. What does "subsequent" mean, is that
> with regards to real time?
>
> So,
>
> Thread 1
> int b = 0;
> volatile boolean a = false;
> ...
> ...
> b = 1;
> a = true;
>
> Thread 2
> if (a) {
> System.out.println("The value of b is " + b);
> }
>
> Since the setting of a to true happens before the reading of a as
> true, the println must happen after b is set to 1.
>
> This means that either nothing will be printed or "The value of b is
> 1" will be printed.
This works as you expect, yes...
>
> Does this work in reverse too?
Not exactly.
>
> For example,
>
> Thread 1
> int b = 0;
> volatile boolean a = false;
> ...
> ...
> a = true;
> b = 1;
>
> Thread 2
> int bStore = b;
> if (!a) {
> System.out.println("The value of b is " + bStore);
> }
>
> Will this always print either "The value of b is 0" or nothing.
>
> (bStore = b) happens before (read a as false)
> (read a as false) happens before (set a = true) [is this valid?]
> (set a = true) happens before (set b = 1)
>
I see no flaw in your reasoning here, though it isn't the "reverse" of
the previous case, it is exactly the same.
> So, bStore = b happens before set b = 1, so bStore = 0.
>
> Effectively, the rule would be "A read to a volatile happens before
> the write to that volatile that overwrites the value that was read".
Yes. that is true.
>
> However, that wasn't clear from the spec. I think since read/writes
> to volatiles are synchronization actions, then when running the
> program, they can be considered to have happened in some ordering
> (consistent with program order in the threads). As long as the
> program works no matter what the ordering is picked, then it is fine.
Yes, that is part of the point.
You may wish to invest in a copy of the book "Java Concurrency in
Practice". It is very thorough, explicit, and understandable explanation
of program behavior under concurrent situations.
[toc] | [prev] | [standalone]
Page 4 of 4 — ← Prev page 1 2 3 [4]
Back to top | Article view | comp.lang.java.programmer
csiph-web