↓ Skip to main content

Java Concurrency: Classic Problems

·575 words·3 mins

Five classic problems cover most of what interviews ask. Producer-consumer is a bounded buffer where producers block when it’s full and consumers block when it’s empty. In real code that’s a BlockingQueue. Dining philosophers is a deadlock through circular wait, fixed by taking forks in a global order. Readers-writers is about letting readers share while writers get exclusive access, without starving the writers. Sleeping barber is a bounded waiting room where customers leave if it’s full, which maps neatly onto offer() and take(). Odd/even printing is two threads taking strict turns on one shared condition.

Part of the Java Concurrency Roadmap. Uses Thread communication, Locks and Concurrent collections.

Producer-consumer
#

Producer-consumerA bounded buffer decouples the two speeds

By hand, with wait/notifyAll:

class BoundedBuffer<T> {
    private final Queue<T> items = new ArrayDeque<>();
    private final int capacity;
    BoundedBuffer(int capacity) { this.capacity = capacity; }

    synchronized void put(T item) throws InterruptedException {
        while (items.size() == capacity) wait();
        items.add(item);
        notifyAll();            // producers and consumers share one wait set
    }

    synchronized T take() throws InterruptedException {
        while (items.isEmpty()) wait();
        T item = items.remove();
        notifyAll();
        return item;
    }
}

In real code:

BlockingQueue<Order> queue = new ArrayBlockingQueue<>(100);
queue.put(order);              // producer
Order o = queue.take();        // consumer

To stop consumers, put a poison pill (a sentinel object) on the queue for each consumer, or interrupt them.

Dining philosophers
#

Five philosophers sit at a round table with five forks. Each one picks up the left fork, then the right. If all five pick up their left fork at once, each waits for a right fork held by a neighbour, and that’s a deadlock.

int first  = Math.min(left, right);   // lower-numbered fork first
int second = Math.max(left, right);
forks[first].lock();
try {
    forks[second].lock();
    try { eat(); } finally { forks[second].unlock(); }
} finally { forks[first].unlock(); }

Taking forks in a global order breaks the circular wait. Two other fixes work too: a Semaphore(4) that lets at most four philosophers reach for forks at once, or tryLock with a random backoff.

Readers-writers
#

Many readers can read together, while a writer needs everyone else out. ReentrantReadWriteLock solves exactly this. The design question is who gets priority: readers first can starve writers, and writers first can starve readers. new ReentrantReadWriteLock(true) makes it fair. Details in Locks.

Sleeping barber
#

One barber, N waiting chairs. The barber sleeps when nobody’s waiting, and a customer who finds every chair taken leaves.

BlockingQueue<Customer> chairs = new ArrayBlockingQueue<>(N);

// customer
if (!chairs.offer(me)) leave();         // full: don't wait, just go

// barber
while (true) cut(chairs.take());        // take() is the sleep

The non-blocking offer models “leave if full”, and the blocking take models “sleep until a customer arrives”.

Printing odd/even with two threads
#

class OddEven {
    private int n = 1;
    private final int max;
    OddEven(int max) { this.max = max; }

    synchronized void run(int parity) throws InterruptedException {   // 1 = odd, 0 = even
        while (true) {
            while (n <= max && n % 2 != parity) wait();
            if (n > max) { notifyAll(); return; }
            System.out.println(Thread.currentThread().getName() + ": " + n++);
            notifyAll();
        }
    }
}
// new Thread(() -> p.run(1), "odd") and new Thread(() -> p.run(0), "even"), with InterruptedException handled

The shared condition is “whose turn is it” (n % 2). The n > max checks let both threads exit cleanly instead of one waiting forever. Another approach uses two Semaphores, odd(1) and even(0): each thread acquires its own semaphore and releases the other’s after it prints.

Amar Singh
Author
Amar Singh
I build stuff

Related