0

私の問題を示すためにサンプルプログラムを書きました。バーテンダー スレッドと 3 つの顧客スレッドがあります。作成されると、それらは同時に実行されます。バーテンダーは、各顧客に飲み物を提供することになっています。

私の問題は、Bartender クラスの run() メソッド内の wait() メソッドが起動しないことです。各 Customer クラスの run() メソッド内の release() メソッドでそれを目覚めさせるつもりでしたが、機能していないようです。それは決して目覚めません。

これを修正するにはどうすればよいですか?アドバイスやコードスニペットを提供できる人に感謝します。

import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Bar {

    Semaphore serving;
    boolean isServing = false;

    public static void main(String[] args) {
        Bar bar = new Bar();
        bar.run();
    }

    public void run() {
        serving = new Semaphore(1);
        Thread bartender = new Thread(new Bartender());
        bartender.start();
        threadSleep(1000);

        Thread customer1 = new Thread(new Customer());
        customer1.start();
        threadSleep(2000);
        Thread customer2 = new Thread(new Customer());
        customer2.start();
        threadSleep(2000);
        Thread customer3 = new Thread(new Customer());
        customer3.start();
    }

    public void threadSleep(int time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException ex) {
            Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public class Bartender implements Runnable {
        public void run() {
            while (true) {
                if (serving.availablePermits() == 0) {
                    synchronized (this) {
                        try {
                            System.out.println("Waiting for Customer notify");
                            wait();
                            System.out.println("Serve drink");
                        } catch (InterruptedException ex) {
                            Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        }
    }

    public class Customer implements Runnable {
        private boolean customerServed = false;

        public void run() {
            if (!customerServed) {
                synchronized (this) {
                    try {
                        serving.acquire();
                        if (serving.availablePermits() == 0 && !serving.hasQueuedThreads()) {
                            notify();
                            isServing = true;
                            System.out.println("Customer: Recieves drink");
                            customerServed = true;
                            serving.release();
                            isServing = false;
                        }
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
    }
}
4

1 に答える 1

2

class Bartenderと_class Customer

synchronized (this) {に変更synchronized (Bar.this) {

wait()に変更Bar.this.wait()

notify()に変更Bar.this.notify()

2 つthisは異なるオブジェクトを参照するため、Bartender起動することはありません。そして、2 つBar.thisは同じオブジェクトを参照するため、Bartender起きます!

于 2013-04-20T05:17:13.460 に答える