Skip to content

Instantly share code, notes, and snippets.

@markselby9
Created September 7, 2016 05:39
Show Gist options
  • Save markselby9/a554ed170706660a5de5ad45228e56af to your computer and use it in GitHub Desktop.
Save markselby9/a554ed170706660a5de5ad45228e56af to your computer and use it in GitHub Desktop.
Producer Comsumer problem using wait() and notify(), in Java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Created by fengchaoyi on 16/9/6.
*/
//Thinking in Java P703
public class ProducerConsumerProblem {
public static void main(String[] args) {
new Restaurant();
}
}
class Restaurant {
// private ArrayList<Meal> mealArrayList;
Meal newMeal;
Waiter waiter;
Chef chef;
ExecutorService executorService = Executors.newCachedThreadPool();
Restaurant() {
this.newMeal = null;
this.waiter = new Waiter(this);
this.chef = new Chef(this);
executorService.execute(waiter);
executorService.execute(chef);
}
}
class Waiter implements Runnable {
private Restaurant restaurant;
Waiter(Restaurant restaurant) {
this.restaurant = restaurant;
this.restaurant.waiter = this;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (restaurant.newMeal == null) {
wait(); // wait for chef's notify()
}
}
Meal nextMeal = restaurant.newMeal;
nextMeal.process();
synchronized (restaurant.chef) {
// synchronized???
restaurant.newMeal = null;
restaurant.chef.notify();
}
}
} catch (InterruptedException e) {
System.out.println("Waiter interrupted");
}
}
}
class Chef implements Runnable {
private Restaurant restaurant;
private int count;
private int materialCount = 10;
Chef(Restaurant restaurant) {
this.restaurant = restaurant;
this.restaurant.chef = this;
this.count = 0;
}
@Override
public synchronized void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (restaurant.newMeal != null) {
wait(); // wait for waiter's notify()
// this lock of chef is automatically released, so that waiter.notify() can catch this lock
}
}
this.count += 1;
if (this.count > this.materialCount) {
System.out.println("Running out of material. Closing...");
restaurant.executorService.shutdownNow();//not shutdown()
}
Meal newMeal = new Meal(this.count);
TimeUnit.MILLISECONDS.sleep(100);
restaurant.newMeal = newMeal;
synchronized (restaurant.waiter) {
System.out.println("notify waiter for meal " + count + " ready.");
restaurant.waiter.notify();
}
}
} catch (InterruptedException e) {
System.out.println("Chef interrupted");
}
}
}
class Meal {
private int number;
Meal(int number) {
this.number = number;
}
void process() {
System.out.println("Meal " + this.number + " is being given to customer!");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment