Layers of Logic

Phase XIV

Concurrency

The phase where your code stops being wrong in ways you can reproduce.

11 sections223 min of reading44 exercises

Every bug so far has been repeatable. Run it again, get the same failure, fix it. This phase is where that stops. Two threads writing to one field lose a write, nothing throws, and the number is different every run. You already saw it in Phase XI, where a parallel stream turned 100,000 into 40,787. Eleven sections on what a thread is, what goes wrong, and the five different tools Java gives you for stopping it, ending with the pool that has been running your parallel streams all along.

When you finish this phase you can

  • Say what a thread has of its own and what it shares, using the areas from Phase XIII
  • Explain a race condition precisely enough to point at the two instructions
  • Say what volatile fixes and what it does not
  • Use synchronized correctly and say what object the lock is actually on
  • Choose between a lock, an atomic and a queue for a given problem
  • Explain compare and swap, and the retry loop built on it
  • Use an executor instead of making threads, and say why that matters
  1. 14.1What a Thread Actually IsYour single threaded program has six threads in it and always has. This section is about what each one owns, what they all share, and why that one split makes everything after it hard.ThreadCore19 min4 exercises
  2. 14.2Two Ways to Make One, and Six StatesExtending Thread and implementing Runnable both work, and one of them spends your only superclass. Then six states, three of which mean a thread is not running for three different reasons.Thread statesCore19 min4 exercises
  3. 14.3Asking a Thread to StopThere is no method that stops a thread, and the one that used to has been made to throw. What replaced it is a request the thread has to agree to, and the way it agrees is easy to get wrong by accident.InterruptionCore19 min4 exercises
  4. 14.4Three Ways Two Threads Break One FieldYou expect 200,000 and get 123,267. Then 115,782. Then 111,996. Nothing throws, the code looks right, and there are three separate problems here rather than one.Race conditionVisibilityCore22 min4 exercises
  5. 14.5The Lock Every Object Already HasOne keyword fixes all three failures from the last section. The thing it locks is not obvious, and two methods that both say synchronized can be locking completely different objects and protecting nothing.Monitor lockCore21 min4 exercises
  6. 14.6Waiting for Something to HappenA lock makes threads take turns. It gives one no way to tell another that the thing it was waiting for has arrived. That needs two more methods, and one rule that looks like a typo.wait and notifyCore20 min4 exercises
  7. 14.7Locks You Can Give Up OnEverything synchronized cannot do, in one package. Try and give up, wait with a deadline, be interrupted, let many readers in at once. The last one is the famous optimisation and it made things seventeen times slower until the reads got long enough.Explicit locksCore21 min4 exercises
  8. 14.8Counting Without a LockOne processor instruction reads, compares and writes as a single unbreakable step. Every lock in the last section is built on it, and using it directly fixes the counter with no waiting at all. It is also slower than a lock once eight threads want it.Compare-and-swapCore20 min4 exercises
  9. 14.9The Value Came BackCompare-and-swap asks whether the value is still what you read. Something can change and change back, the comparison succeeds, and everything you concluded from it is wrong. Reading the code more carefully will not help.The ABA problemCore19 min4 exercises
  10. 14.10Stop Making ThreadsA thread costs a megabyte, runs once, returns nothing and loses its failures. A pool fixes all four, and the factory method everyone uses to build one has a queue that will accept two billion tasks before it complains.Executor and FutureCore21 min4 exercises
  11. 14.11Futures That Do Not Block, and Threads That Are Nearly FreeThe machine gave up at 2,027 platform threads. It ran a million virtual ones in three seconds. The last section of the course is also the one that quietly removes the reason for the previous one.CompletableFutureVirtual threadCore22 min4 exercises