HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Simple multithreading task

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
multithreadingsimpletask

Problem

I wrote program which simulates the work of the restaurant. It works but I would like to change it because I think there is better solution.Thanks for your suggestions.

Client.java

public class Client implements Runnable {
    private Restaurant r;

    public void makeOrder() throws InterruptedException {
        synchronized (r) {
            r.notifyAll();
            System.out.println("Start ordering ");
            Thread.sleep(1000);
            r.putOrderMadeByClient(r.orderId);
            System.out.println("End ordering ");
            while(r.orderReceived==false)
                r.wait();
            r.getOrderReceived();
        }
    }

    public Client(Restaurant r) {
        this.r=r;
    }

    public void run() {
        try {
            makeOrder();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


Waiter.java

public class Waiter implements Runnable {
    private Restaurant r;

    public void makeServe() throws InterruptedException {
        synchronized (r) {
            r.notifyAll();
            while(r.orderMadeByClient==false)
                r.wait();
            System.out.println("Start serving order ");
            Thread.sleep(1000);
            r.putOrder(r.getOrderMadeByClient());
            while(r.orderReady==false)
                r.wait();
            r.putOrderReceived(r.getFood());   
            System.out.println("End serving order ");
        }
    }

    public Waiter(Restaurant r) {
        this.r=r;
    }

    @Override
    public void run() {
        try {
            makeServe();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


Chef.java

```
public class Chef implements Runnable {
private Restaurant r;

public void makeFood() throws InterruptedException {
synchronized (r) {
r.notifyAll();
while(r.orderTaken==false)
r.wait();
System.out.print

Solution

The main issue here is that everything synchronizes on the restaurant object. This means that the chef cannot prepare food while the client is placing an order, waiters cannot serve while the chef is cooking, etc. The first step would be to add BlockingQueues to Restaurant and let them manage all of the calls to wait() and notify() for you.

You'd need one queue of orders that waiters place and chefs take and another for food that chefs place and waiters take. When a Chef calls take() on the order queue, it will block until there is an order available. A Waiter calling offer() on the same queue will block until there is room in the queue. You can make the queues bounded (maximum size) or unbounded.

You might even create a queue to hold the clients waiting to place orders. Waiters would poll() the food and client queues in their run() loop so they don't wait forever for food to be ready when they haven't even placed any orders yet.

public void run() {
    while (true) {
        Food f = foodQueue.poll(2, TimeUnit.SECONDS);
        if (f != null) {
            // deliver food to client...
        }
        Order o = clientQueue.poll(2, TimeUnit.SECONDS);
        if (o != null) {
            if (!orderQueue.offer(o, 120, TimeUnit.SECONDS)) {
                // kitchen is too busy!
                break; // waiter quits out of frustration
            }
        }
    }
}


The Chef class currently waits for a second and then takes the order and makes the food available immediately. Instead, it should take the order, then wait, and finally make the food available. If you were to create a queue for the use of the chef while cooking, you could use a priority queue (orders the elements in the queue) and have different types of food take different lengths of time to prepare. The chef would then have multiple things cooking at once and deliver each after its own cook time has expired.

With the above in place you could really kick this into high gear by creating multiple waiters and chefs and add a separate thread that randomly creates clients that place random orders.

Code Snippets

public void run() {
    while (true) {
        Food f = foodQueue.poll(2, TimeUnit.SECONDS);
        if (f != null) {
            // deliver food to client...
        }
        Order o = clientQueue.poll(2, TimeUnit.SECONDS);
        if (o != null) {
            if (!orderQueue.offer(o, 120, TimeUnit.SECONDS)) {
                // kitchen is too busy!
                break; // waiter quits out of frustration
            }
        }
    }
}

Context

StackExchange Code Review Q#3001, answer score: 4

Revisions (0)

No revisions yet.