[2019 oracle code one] java concurrency

Java Concurrency, A(nother) Peak Under the Hood

Speakers: David Buck (Oracle) – @DavidBuckJP

For more blog posts, see The Oracle Code One table of contents


Multi threaded code use cases

  • GUIs
  • Libraries
  • Batch Processing
  • Worst case: writing multi-threaded code but don’t know you are

Problems

  • Race conditions
  • Heisenbugs/observer problem – occur in Prod (or locally), but disappear in debugger

Tools

  • Java memory model
  • synchronized keyword
  • java.util.concurrent

Memory model

  • What guarantees do you have that writes in one thread are available to another thread?
    • Local variables safe
    • Static variables/instance variables can introduce concurrency problems
    • JIT compiler can change order things are done (vs the order you code them in)
    • If optimizing compiler sees a = 1 and a=a+1, compiler will just initialize a to 2.
    • Out of order execution – hardware can execute out of order to improve performance
  • Clartify what multithreaded behavior developers may depend on. Limits what types of optimizations the runtime can do
  • Spec: https://docs.oracle.com/javase/specs/jls/se13/html/jls-17.html

Things Java Protects us from

  • Testing on Raspberry Pi because ARM so can see problems that don’t occur on Intel chips
  • memory barrier/fence
  • prevents reordering before before/after fence. How do to this varies by processor./tool chain. Need to set two – one on read and one on write to guarantee behavior for testing.
  • Types: store-store, store-load, load-store, load-load

Relativity

  • As in physics, no single “correct” timelines
  • Observed order of events depends on frame of reference
  • Each core can have slightly different view of memory
  • This means core files aren’t 100% accurate

Changes to memory model

  • Originally only dealt with synchronized – mutual exclusion and happened-before. Volatile was defined but just about visibility
  • This was a problem because volatile didn’t enforce happened-before and final values could change.
  • Java 5 adopted Doug Lea’s open source APIs (JSR-166)
  • JSR-133 – ensured volatile does establish happens-before and final values will never changed
  • Volatile != atomic
  • id++ still not thread safe on a volatile field. Can use synchronized to fix
  • In original memory model, 64-bit numbers (longs and doubles) not updated atomically

Practical advice

  • Use highest level construct available. java.util.concurrency > synchronized/wait/notify. Last choice is volatile/final
  • Don’t roll your own. Even Doug Lea didn’t get it perfect
  • Java 8 – Lambdas/streams – high level
  • Java 9 – Var handles – lower level than volatile/final. Alllows value to be volatile only when we want it to be. Explicit fence/acquire/release. This was introduced for use cases sun.misc.Unsafe used to deal with.

My take

This was really interesting. It was like a peek behind the curtain! My only complain is that dark red text on a black background is hard to read. Luckily there wasn’t much of it and it was obvious what was being “emphasized” in red. Also, I liked the demos!

Leave a Reply

Your email address will not be published.