Reputation: 3
I'm newbie in programming so I decided to write a simple multithreading program. It shows the work of the restaurant.Client orders food,waiter serves and cook prepares it. But I've got a problem, I think this is the case of deadlocking because when I run it, it prints "ordering" and nothing else. I can't understand what is wrong. Please help.Thanks.
Restaurant.java
public class Restaurant implements Runnable{
Client cl=new Client();
Chef ch=new Chef();
Waiter w=new Waiter();
public synchronized void makeOrder() throws InterruptedException{
notifyAll();
cl.makeOrder();
wait();
}
public synchronized void makeServing() throws InterruptedException{
notifyAll();
wait();
}
public synchronized void makeFood() throws InterruptedException{
notifyAll();
ch.makeFood();
Thread.sleep(1000);
wait();
}
@Override
public void run() {
try {
for(int i=0;i<10;i++){
makeOrder();
makeServing();
makeFood();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Client.java
public class Client{
public void makeOrder(){
System.out.println("Ordering"+Thread.currentThread().getId());
}
Waiter.java
public class Waiter {
public void makeServe() {
System.out.println("Serving order"+Thread.currentThread().getId());
}
Chef.java
public class Chef {
public void makeFood(){
System.out.println("Making food "+Thread.currentThread().getId());
}
Main.java
public class Main {
public static void main(String[] args) {
Restaurant r=new Restaurant();
Thread t=new Thread(r);
t.start();
}
}
Upvotes: 0
Views: 3530
Reputation: 18455
If you want to learn multithreading by modelling a restaurant, then try this model;
Have a Restaurant
class. Note that a restaurant is not Runnable
because a restaurant itself it doesn't do anything (the people inside it do). The restaurant instead contains the other classes that actually 'do stuff'.
Have a Waiter
class. A waiter should periodically (e.g. every 1 minute) check the restaurant for customers waiting to order. If it finds a customer who wants to order it creates an order and adds it to a order queue. Your restaurant can contain several Waiter
instances.
Have a Chef
class. The chef subscribes to the order queue that the waiters write to. Whenever a new order is created the chef cooks the order (this should take some time, eg 2 minutes) and then alerts any free waiter. The waiter then serves the food to the customer. Your restaurant can container several Chef
instances.
Have a Customer
class. Customers should visit the restaurant at random intervals. They wait for a waiter to take their order, wait for the food to arrive, eat the food then leave. For bonus points give your restaurant a capacity and turn customers away/make them wait when it is full.
Concepts used in this example
Upvotes: 5
Reputation: 8560
When you call makeOrder();
in the Restaurant thread it will wait(). And then nothing will happen anymore. The problem is, that you have only one thread, this one cannot notify itself. I think what you want to do is turn your Client, Waiter and Chef into threads. Then start them one after another and then the Waiter has to wait until the Client made his order and the Chef has to wait until the Waiter got the order...
You might find some helpful examples if you google for "java producer consumer example".
Upvotes: 5
Reputation: 223173
You are misusing the wait/notify mechanism. :-) That's the real problem.
In Java, wait/notify is used to implement condition variables, which allows a thread to wait for a "condition" to be fulfilled. Another thread can also notify any waiting threads that said condition "may" be fulfilled, and to recheck the condition.
Here's a simple example:
public class Exchanger<T> {
private T item;
public synchronized T poll() {
while (item == null)
wait();
T result = item;
item = null;
notifyAll();
return result;
}
public synchronized void offer(T value) {
if (value == null)
throw new NullPointerException();
while (item != null)
wait();
item = value;
notifyAll();
}
}
There are two conditions here (wrapped up under one condition variable, which normally isn't very kosher, but):
Basically, whenever poll
or offer
is called, it blocks until another thread does an offer
or poll
, respectively. To test for when to block, it does the relevant checks within the while
loop.
Upvotes: 1
Reputation: 10959
Your code works (gives output) if you are using a main method that looks like this:
public static void main(String[] args) {
Restaurant r = new Restaurant();
new Thread(r).start();
new Thread(r).start();
new Thread(r).start();
}
The program will run for a while, and will then halt since it will wait for more "requests", it's not stuck in a deadlock. A deadlock requires two different locks, and you only got one in your code.
Note that you still might have logical "flaws/bugs"
Upvotes: 0