Challenge 1: Reproducing a Real Race Condition — Possible Solution ==================================================================== RaceDemo.java: public class RaceDemo { static class Counter { private int count = 0; public void increment() { count++; } public int getCount() { return count; } } public static void main(String[] args) throws InterruptedException { Counter counter = new Counter(); Runnable task = () -> { for (int i = 0; i < 100_000; i++) { counter.increment(); } }; Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("Final count: " + counter.getCount()); } } Representative output (varies run to run, but reliably under 200,000): Final count: 187342 Explanation: Both threads call the unsynchronized increment() concurrently, 100,000 times each. Because count++ is really a read-then-modify-then-write sequence, both threads can read the same value before either writes its update back, silently losing one of the two increments. join() ensures main waits for both threads to finish before printing, so the result reflects all 200,000 increment() calls -- yet the total is consistently less than 200,000 due to lost updates. WHY THIS WORKS AS AN ANSWER ------------------------------ This reproduces the exact race condition the chapter describes -- two threads incrementing shared state through an unsynchronized method -- with join() used correctly to ensure the final count is read only after both threads have truly finished, confirming the lost updates are a real, reproducible effect rather than a timing artifact of reading too early.