[concurrency-interest] question the about the JMM

Peter Veentjer alarmnummer at gmail.com
Wed Dec 5 17:05:02 EST 2007


On Dec 5, 2007 10:56 PM, Brian Goetz <brian at briangoetz.com> wrote:
> > I'm having a discussion with a a very smart colleague about some
> > example (from iBatis) that in my opinion has a visibility problem and
> > in his opinion doesn't.
>
> I reviewed your colleague's e-mail again.  I had mistakenly switched the
> positions: I thought _he_ was saying "there is a visibility problem" and
> his colleague (you, apparently) that there was not.  But my intention
> was to say "this code is broken", and the comments in the message should
> make that clear.
>
> Unless something() is called from the same thread as setFlag(), it is
> not guaranteed to _ever_ see flag be true unless it acquires the lock
> acquired by the writing thread.

>
> Oh, and by the way, in:
>
>  >    synchronized (new Object()) {
>  >      // unimportant
>  >    }
>
> the synchronization has no effect in any case.  The compiler can prove
> that no other thread could synchronize on the same object, and is thus
> permitted to eliminate the sync entirely.

That is true and something I saw. But a new object is not created just
for synchronization sake, instead some argument that is passed is
used, but it was removed to simplify this example.

> On a tangentially related note, it is in very poor taste to forward a
> private message to a public list without the author's permission; doubly
> so because it was sent to someone else, not you.

I can understand that and I'm sorry.

>
>
>
> >
> > This is the example:
> >
> >  private boolean flag = true;
> >
> >  public void something() {
> >    if (flag) {
> >      synchronized (this) { // synchronized block
> >        // do something
> >      }
> >    } else {
> >      // do something else with very little impact, NOT inside a
> >  synchronized block
> >    }
> >  }
> >
> > public void setFlag(boolean newFlag) {
> >    this.flag = newFlag;
> >    synchronized (new Object()) { // ANOTHER MONITOR THAN IN METHOD something
> >      // unimportant
> >    }
> >  }
> >
> > With my current understanding of the JMM I would expect that the flag
> > variable has a visibility problem. Because there is no happens before
> > relation between the write in the setFlag method, and the read in the
> > something method, a thread that runs the something method doesn't need
> > to see the written value by a different thread ever.
> >
> > The problem could be solved by using the the monitor lock rule (using
> > the lock of the object itself) or the volatile read/write rule. So the
> > simplest thing to remove the visibility problem is to make the flag
> > volatile.
> >
> > The question is, am I correct? Does this example contain a visibility problem?
> >
> > To make things more complicated, we have asked Brian Goetz and
> > according to him my colleague is right.
> >
> > this is the mail conversion between them:
> >
> > rom: Brian Goetz [mailto:brian at briangoetz.com]
> > Sent: Wed 12/5/2007 16:41
> > To: Erwin Bolwidt
> > Subject: Re: JMM question (wrt to a statement you made at JavaPolis)
> >
> > Your colleague is wrong.
> >
> > Both of the statements you refer to are correct.  The key is that only
> > synchronization actions (reads and writes of volatiles, and acquire and
> > release of locks) need to be totally ordered.  So if thread A release a
> > lock "before" thread B acquires one, that doesn't mean anything, because
> > the threads don't share your concept of "before".
> >
> > The primary mistake people make in approaching concurrency is to falsely
> > assume "sequential consistency", meaning that "everything happens in a
> > fixed, global order".  In reality, it is more like the thought
> > experiments you did in special relativity, where ordering is relative to
> > the observer.  This happens in modern CPUs too, in the absence of
> > adequate synchronization.  The only total ordering you can rely on is
> > synchronization actions.  This is why if we synchronize on a common
> > lock, things work properly -- because it is sensible to speak of "when
> > you release the lock and I subsequently acquire it."  When we acquire
> > different locks, there is no way to guarantee "subsequent".  (And when
> > we don't acquire locks at all, it isn't even meaningful to talk about
> > "subsequent.")
> >
> > Any logic that relies on unsynchronized reads of shared references to
> > mutable objects is committing the same error as double-checked locking,
> > with the same possible consequences.
> >
> > The rules for the new memory model (happens-before) are actually fairly
> > simple to reason through.  Its the "I (think I) know what's going on in
> > the machine" part that leads people into trouble.  Such reasoning
> > invariably amounts to "I don't believe these are really the rules."
> >
> > Erwin Bolwidt wrote:
> >> Hi Brian,
> >>
> >> A collegue and are having a discussion about one aspect of the new Java
> >> Memory Model.
> >> After one of your presentations on the JMM I asked you about how
> >> specific volatile or synchronized is (at JavaPolis I believe but it
> >> could have been JavaOne)
> >>
> >> Specifically, I wondered if synchronized on different monitors or access
> >> to different volatile variables were really independent: if these would
> >> only cause related data to be synchronized (written out to/invalidated
> >> L1/2 caches) with "global" memory or if they would effectively
> >> synchronize the whole thread state (caches) with "global" memory.
> >> You response as I remember it was that the latter was the case: the
> >> whole thread state (caches) would be synchronized. The former would be
> >> too complicated to implement.
> >>
> >> The JSR 133 FAQ (co-authored by you) at
> >> http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html states:
> >>
> >>         *Important Note:* Note that it is important for both threads to
> >>         synchronize on the same monitor in order to set up the
> >>         happens-before relationship properly. It is not the case that
> >>         everything visible to thread A when it synchronizes on object X
> >>         becomes visible to thread B after it synchronizes on object Y.
> >>         The release and acquire have to "match" (i.e., be performed on
> >>         the same monitor) to have the right semantics. Otherwise, the
> >>         code has a data race.
> >>
> >> Now I realize that possibly both statements are true, and that this
> >> boils down to a misunderstanding of terms like "happens-before
> >> relationship".
> >>
> >> I have an example and I'm not sure what would happen here. In the real
> >> case, "flag" was called "cacheEnabled" and the question was whether the
> >> cache could be turned off in a way that would be guaranteed to work.
> >> This looks a little like the double-check locking issue. My statement
> >> was that if "setFlag(false)" was called on one thread, the something()
> >> method on another thread would be guaranteed to see this
> >> _the_second_time_ the method was entered, because the synchronization
> >> would invalidate the CPU caches on the thread that runs something(), and
> >> likewise the synchronized on a different monitor in setFlag would write
> >> out the change to the field "flag" to global memory.
> >>
> >> My collegue disagrees. Can you tell who is right?
> >>
> >> Thanks a lot if you can spend some time on this.
> >>
> >> Regards,
> >>   Erwin Bolwidt
> >>
> >> -------------- Example code --------------
> >>
> >> private boolean flag = true;
> >>
> >> public void something() {
> >>   if (flag) {
> >>     synchronized (this) { // synchronized block
> >>       // do something
> >>     }
> >>   } else {
> >>     // do something else with very little impact, NOT inside a
> >> synchronized block
> >>   }
> >> }
> >>
> >> public void setFlag(boolean newFlag) {
> >>   this.flag = newFlag;
> >>   synchronized (new Object()) { // ANOTHER MONITOR THAN IN METHOD something
> >>     // unimportant
> >>   }
> >> }
> >>
> >>
> >> --
> >> Erwin Bolwidt
> >> business consultant
> >>
>
> > _______________________________________________
> > Concurrency-interest mailing list
> > Concurrency-interest at altair.cs.oswego.edu
> > http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>


More information about the Concurrency-interest mailing list