On Thu, Apr 15, 2010 at 5:26 PM, Ryan Rawson <ryano...@gmail.com> wrote:

> Looking at the code to AtomicBoolean it uses an atomic int to
> accomplish it's task on OSX.
>
> So just what the heck is going on here?
>
>
I think you're fooling yourself, and the bug isn't gone, just hiding :)

-Todd


>  On Thu, Apr 15, 2010 at 5:24 PM, Ryan Rawson <ryano...@gmail.com> wrote:
> > I doubt it's case #2, there is a lot of complex code that runs between
> > putThread.start() and putThread.done().
> >
> > In terms of JVMs, I'm using Java 6 on OSX x64.  HBase effectively
> > requires Java 6 (and if we dont explicitly require it, we should) and
> > it also specifically cannot use certain broken JVM pushes (eg:
> > jdk6u18) so much that we are adding in code to prevent ourselves from
> > running on it and warning the user.
> >
> > But just for a moment, I think it's inappropriate for the JVM to be
> > specifying caching or non-caching of variables in the systems cache.
> > That is way too much abstraction leakage up to the language level.
> > Most SMP systems have cache coherency control that allow you to read
> > from cache yet get invalidations when other processors (on other dies)
> > write to that memory entry.
> >
> > But nevertheless, the problem no longer exists with AtomicBoolean :-)
> >
> >
> >
> > On Thu, Apr 15, 2010 at 5:05 PM, Paul Cowan <co...@aconex.com> wrote:
> >> On -9/01/37 05:59, Ryan Rawson wrote:
> >>>
> >>> So the previous use of volatile for a boolean seems like a textbook
> >>> case, but the situation i discovered was pretty clear cut. I have no
> >>> other explanation than a highly delayed volatile read (which are
> >>> allowed).
> >>
> >> I don't see that they are allowed, actually.
> >>
> >> Section 17.4.5 of the JLS says that:
> >>
> >>> * An unlock on a monitor happens-before every subsequent lock on that
> >>> monitor.
> >>> * A write to a volatile field (§8.3.1.4) happens-before every
> subsequent
> >>> read of that field.
> >>
> >> IOW, the situations (unlock-then-lock) and (volatile-write then
> >> volatile-read) have the same visibility guarantees.
> >>
> >> Section 8.3.1.4 says:
> >>
> >>> A field may be declared volatile, in which case the Java memory model
> >>> (§17)  ensures that all threads see a consistent value for the
> variable.
> >>
> >> In your case, the thread calling done() is not seeing the same value as
> the
> >> thread calling run(), which is not consistent.
> >>
> >> And for good measure Java Concurrency in Practice makes it much more
> >> explicit (emphasis mine):
> >>
> >>> Volatile variables are not cached in registers or in caches where they
> are
> >>> hidden from other processors, so *a read of a volatile variable always
> >>> returns the most recent write by any thread*.
> >>
> >> And finally, on changing to an AtomicBoolean fixing the problem, JCIP
> says:
> >>
> >>> Atomic variables offer the same memory semantics as volatile variables
> >>
> >> So this doesn't really make sense either.
> >>
> >> All that's a long way of saying that the only ways I can see your
> situation
> >> happening are:
> >>
> >> * pre-Java-1.5 (and hence pre-JSR-133) JVM
> >> * JVM with a bug
> >> * ordering is not as you expect, i.e. the actual chronological order is
> not:
> >>
> >>    THREAD 1                 THREAD 2
> >>    spawn new thread
> >>                             run()
> >>    done()
> >>    join()
> >>
> >> but rather:
> >>
> >>    THREAD 1                 THREAD 2
> >>    spawn new thread
> >>    done()
> >>                             run()
> >>    join()
> >>
> >> in which case the set of run to false at the start of run() overwrites
> the
> >> set of it to true at the start of done(), and you're in for infinite
> loop
> >> fun.
> >>
> >> Cheers,
> >>
> >> Paul
> >>
> >
>



-- 
Todd Lipcon
Software Engineer, Cloudera

Reply via email to