4 ms·
> Without looking it up do you know what are the Java memory model guarantees? * Java is a happens-before language--you need a sequence of X happens-before Y f
by jcranmer 3y ago
> Without looking it up do you know what are the Java memory model guarantees?
* Java is a happens-before language--you need a sequence of X happens-before Y from a write to a read that crosses threads for the language to be well-defined. I'm not going to list the "obvious" cases of happens-before relations.
* volatile variables in Java are sequentially consistent atomic variables.
* 64-bit loads are atomic in the sense that word tearing cannot be observed.
* Writes to a final variable in an object's constructor happen-before the end of constructing an object. (Probably the easiest thing for people to forget)
* There's a bunch of complex rules to try to explain what happens if you violate happens-before and you have a data race. These aren't really right anyways, so you can safely ignore these and pretend it's UB if you do create a data race, which is what happens in other happens-before language models.
> Or what's the difference between >> and >>> ?
The first is arithmetic shift right and the second is logical sign right; alternatively, the first will copy the sign bit into the lower vacated bits while the latter does not.
- tialaramex 3y ago> you can safely ignore these and pretend it's UB if you do create a data race I mean, that's safe but it's thoroughly unnecessary. In a language where races are UB all bets are off and that's a pretty wild consequence for what may be a relatively minor mistake. Because data races aren't UB in Java, our program even though its behaviour now likely defies ordinary understanding by its creators, does still have some coherent behaviour. For example maybe we raced code that's putting CustomerOrders in a List, and so the List is smashed. In a language like C++ it's entirely possible that the smashed List is so toxic that even asking how big it is potentially has completely insane answers, crashes, runs arbitrary code, anything might happen - let alone if trying to take all the CustomerOrders out one at a time for processing. In Java, maybe the List is empty, which is not what we wanted, or it has all the orders which shouldn't be there, it won't have for example a negative number of CustomerOrders or anything else completely nonsensical. In terms of defensible business logic, Java's memory model isn't better. But in terms of "Do attackers who exploited my race also get to run arbitrary machine code with database access?" the answer is definitely going to be "No" in Java for a data race, unlike in C++ or even Go. Also, while it's true that Undefined Behaviour is common for data races (because of SC/DRF and laziness), it's not what happens in OCaml, they've come up with an even cleverer scheme than Java so that they hope their programs remain not only strictly well defined, but maybe something you can reason about despite a data race.
- kaba0 3y ago> 64-bit loads are atomic in the sense that word tearing cannot be observed. This is true in practice in case of most JVM implementations, but is not in fact mandated by the spec — only 32bit values are loaded atomically according to that (so on a 32bit JVM you might observe ‘tearing’). Nonetheless, I also think that you can pretty much hold all of Java in your head, as opposed to C++.