The Pizza Problem – Concurrent Programming

A group of students are studying for an exam. The students can study only while eating pizza. Each student executes the following loop:

while (true) {
pick up a slice of pizza;
study while eating the pizza;
}

If a student finds that the pizza is gone, the student goes to sleep until another pizza arrives. The first student to discover that the group is out of pizza calls Kamal’s Pizza to order another pizza before going to sleep. Each pizza has S slices. Once Kamal delivers pizza, he wake up all the students in the group. Then the students pick up a slice of pizza and go back to studying, and the process continues.

Write code to synchronize the student threads and the Kamal’s pizza delivery thread.

Your solution should avoid deadlock and call Kamal’s Pizza (i.e., wake up the delivery thread) exactly once each time a pizza is exhausted. No slice/piece of pizza may be consumed by more than one student.

Solution

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.

Discussion

If a student finds that the pizza is gone, the student goes to sleep until another pizza arrives. Once the pizza is delivered, the delivery person should wake up all the sleeping students. In order to simulate this behavior, we have to use a special type of construct named Condition Variable.

What are Condition Variable?

Condition variables allow to check for a condition, and makes a thread wait until the condition is satisfied. When the condition is satisfied, it will wake up the sleeping thread. There is a special method to broadcast and wake up all the sleeping threads as well.

In Java, you can create conditions using the newCondition method of the Lock (lines 41 and 42). A condition is a variable of type Condition. You can make the current thread wait on the condition using the await() method and you can signal threads using signal() and signalAll() methods. The signalAll() method wakes up all the threads waiting on the condition variable.

What happens in the code?

In the code given above, if a Student thread sees that the slice count is zero, it should go to sleep. This is done at line 60; deliverPizza.await().

The first student to see that the slice count is zero, wakes up the pizza delivery thread. This is done at line 56; orderPizza.signal(). Then he goes to sleep like other students at line 60.

Once pizza is delivered and the plate is full, the pizza delivery thread wakes up all the sleeping student threads. This is done at line 72; deliverPizza.signalAll(). This is a broadcast signal for all the student threads to wake up.

Resources

You can find the complete organized solution in my GitHub repository here.

References

Condition (Java Platform SE 7) – https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html

Java Concurrency – Part 5 : Monitors (Locks and Conditions) – https://baptiste-wicht.com/posts/2010/09/java-concurrency-part-5-monitors-locks-and-conditions.html

Late-Night Pizza – courses.cs.washington.edu/courses/cse451/10wi/section/kim_section4.ppt