×

java · level 3 · unit 5 · lesson 2

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. nailed it

Tap a green word if you get lost.

meet it

Two threads, one counter: a waiting to happen.

count++ looks like one step but is three: read the value, add one, write it back. If two threads read 41 at the same moment, both write 42, and one update is lost. A bug like this, where the result depends on timing, is a race condition.

Races hide. A program can pass a thousand runs, then lose a sale on the busiest day. You cannot test them away, so you design them out.

Mark the method . Each object has one , and a thread must hold it to enter. Others wait their turn, so the read, add and write happen together. Every thread must share the same object, or each has its own lock and nothing is protected.

public class Main {
    static class Tills {
        private int sales = 0;
        synchronized void sell() {
            sales++;
        }
        synchronized int total() { return sales; }
    }
    static void shift(Tills tills) {
        for (int i = 0; i < 50000; i++) {
            tills.sell();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Tills shop = new Tills();
        Thread morning = new Thread(() -> shift(shop));
        Thread evening = new Thread(() -> shift(shop));
        morning.start();
        evening.start();
        morning.join();
        evening.join();
        System.out.println("Sales: " + shop.total());
    }
}

Remove synchronized from sell and the total would come out short, by a different amount each run.