Created
September 7, 2016 05:39
-
-
Save markselby9/a554ed170706660a5de5ad45228e56af to your computer and use it in GitHub Desktop.
Producer Comsumer problem using wait() and notify(), in Java
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.
Learn more about bidirectional Unicode characters
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