Hacker News new | ask | show | jobs
by layer8 1356 days ago
> I’m not talking about data races. Data races are typically bugs, by definition.

One notable exception is the Racy Single-Check Idiom: http://javaagile.blogspot.com/2013/05/the-racy-single-check-...

It is particularly suitable for lazy initialization in code that is typically (but not necessarily) executed single-threaded, and is famously used in Java’s String.hashCode() implementation.

1 comments

That's a nice example. It seems that data races in Java don't "catch fire"; is that correct? The catch-fire problem is pretty bad for languages like C/C++, which have undefined behavior for data races, and in this sense data races are "bugs by definition" in those languages.
Java’s primitives and references are guaranteed to be “tear-free”, which guarantees no “out-of-thin-air” values. So a field set to 1 and being written by several threads to 2 and 3 can only ever be observed as 1,2 or 3, no other value. Is that what you mean under not catching fire?
Perfect. Yes, that's exactly right -- if the language semantics is able to guarantee a set of possible values for a data-racy read, then it doesn't catch fire.

The catch-fire terminology comes from the analogy that, as soon as a data race occurs, the semantics of the program completely explodes, and all guarantees are lost---the program is then allowed to do literally anything. This is sometimes known as "DRF-SC or catch fire": either the program is data-race-free (and therefore its executions are sequentially consistent), or the program has undefined behavior.

Infamously, the C memory model has the catch-fire problem. And therefore, any language which relies on the C memory model can catch-fire. As of today, I believe this includes C/C++, Swift, Rust, and probably a few others.

> Java’s primitives and references are guaranteed to be “tear-free”, which guarantees no “out-of-thin-air” values

Tear-free does not imply no out-of-thin-air. But, afaik, the java memory model protects from both tearing and oota.

Yeah, you are right, I was not clear in my wording.
I think catching fire here refers to the general "this is UB and all bets are off" situation. For example, if you're data racing against an int on x86-64 Linux, you might reason that the `mov` instruction on that platform can't possibly product torn reads. And you'd be right as far as that goes. But the C/C++/Rust compiler still considers those data races UB and may still do horrible things like just deleting big chunks of your code if it manages to prove that that's what you've done.