Простая задача многопоточности


Я написал программу, которая имитирует работу ресторана. Это работает, но я хочу изменить это, потому что я думаю, что есть лучшее решение.Спасибо за ваши предложения.

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.println("Start making food ");
            Thread.sleep(1000);
            r.putFood(r.getOrder());
            System.out.println("End making food ");
        }
    }

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

    @Override
    public void run() {
        try {
            makeFood();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Restaurant.java

public class Restaurant {
    boolean orderMadeByClient;
    boolean orderTaken;
    boolean orderReady;
    boolean orderReceived;
    long orderId;

    public Restaurant() {
    }

    public void makeRestaurant() {
        Client cl = new Client(this);
        Chef ch = new Chef(this);
        Waiter w = new Waiter(this);
        Thread t1 = new Thread(cl);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(ch);

        t1.start();
        t2.start();
        t3.start();
    }

    synchronized long getOrderMadeByClient() {
        while (!orderMadeByClient) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        orderMadeByClient = false;
        notifyAll();
        System.out.println("get order from client #" + orderId);
        return orderId;
    }

    synchronized void putOrderMadeByClient(long l) {
        while (orderMadeByClient) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        orderMadeByClient = true;
        this.orderId = l;
        notifyAll();
        System.out.println("put order client #" + l);
    }

    synchronized long getOrder() {
        while (!orderTaken) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        orderTaken = false;
        notifyAll();
        System.out.println("get order from waiter #" + orderId);
        return orderId;
    }

    synchronized void putOrder(long l) {
        while (orderTaken) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        orderTaken = true;
        this.orderId = l;
        notifyAll();
        System.out.println("put order to cook #" + l);
    }

    synchronized long getFood() {
        while (!orderReady) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        orderReady = false;
        notifyAll();
        System.out.println("get order by waiter #" + orderId);
        return orderId;
    }

    synchronized void putFood(long n) {
        while (orderReady) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        orderReady = true;
        this.orderId = n;
        notifyAll();
        System.out.println("put order by cook #" + n);
    }

    synchronized long getOrderReceived() {
        while (!orderReceived) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        orderReceived = false;
        notifyAll();
        System.out.println("get order by client #" + orderId);
        return orderId;
    }

    synchronized void putOrderReceived(long l) {
        while (orderReceived) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        orderReceived = true;
        this.orderId = l;
        notifyAll();
        System.out.println("put order by waiter #" + l);
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        Restaurant r=new Restaurant();
        r.makeRestaurant();
    }
}


3680
5
задан 18 июня 2011 в 02:06 Источник Поделиться
Комментарии
1 ответ

Основная проблема здесь заключается в том, что все синхронизируется на объект "ресторан". Это означает, что шеф-повар не может готовить пищу в то время как клиент делает заказ, официанты не могут обслужить, а шеф-повар приготовление пищи и т. д. Первым шагом будет добавление интерфейса blockingqueues в ресторане и позволить им управлять все призывы подождать() и сообщить() для вас.

Вам понадобится одна очередь из заказов, что официант и повара и другой еды, повара и официанты место занять. Когда шеф-повар призывает принять() в порядке очереди, он будет блокировать, пока есть заказ в наличии. А официанта называть предложение() на одну и ту же очередь будет блокировать, пока есть место в очереди. Вы можете сделать очередях ограничен (максимальный размер) или без ограничений.

Вы можете даже создать очередь, чтобы удержать клиентас ждут, чтобы размещать заказы. Официантбудет опрос() еда и клиентских очередей в их ведении() петли, чтобы они не ждать, пока еда будет готова, когда они еще не размещал заказы еще.

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
}
}
}
}

В шеф-повар класса в настоящее время ждет второго, а затем принимает заказ и делает пищи сразу. Вместо этого он должен принять заказ, потом ждать, и, наконец, принять пищи. Если вы были, чтобы создать очередь для использования шеф-повара во время приготовления пищи, можно использовать приоритетную очередь (приказы элементов в очереди) и разные виды пищи принимать различные промежутки времени, чтобы подготовиться. Затем шеф-повар будет иметь несколько дел сразу и поставить каждый по своему Время приготовления истекло.

С помощью данной вы могли бы действительно этот удар на большой скорости, создав несколько официантов и поваров и добавить отдельный поток, который случайным образом создает клиентам, что место случайных заказов.

4
ответ дан 18 июня 2011 в 06:06 Источник Поделиться