At least it's in test code right? *sigh*
On Thu, Apr 15, 2010 at 5:27 PM, Todd Lipcon <t...@cloudera.com> wrote: > 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 >