【问题标题】:Why is my release() method not waking my instance?为什么我的 release() 方法没有唤醒我的实例?
【发布时间】:2013-04-20 05:09:59
【问题描述】:

我编写了一个示例程序来演示我的问题。 有一个调酒师线程和三个客户线程。 它们在创建后同时运行。 调酒师应该为每位顾客提供一杯饮料。

我的问题是调酒师类 run() 方法中的 wait() 方法永远不会唤醒。 我原本打算让每个 Customer 类的 run() 方法中的 release() 方法唤醒它,但它似乎不起作用。它永远不会醒来。

我该如何解决这个问题? 感谢任何可以提供建议或编码 sn-ps 的人。

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

【问题讨论】:

    标签: java multithreading concurrency semaphore notify


    【解决方案1】:

    class Bartenderclass Customer

    synchronized (this) { 更改为synchronized (Bar.this) {

    wait() 更改为Bar.this.wait()

    notify() 更改为Bar.this.notify()

    因为两个this 引用不同的对象,Bartender 永远不会唤醒。因为两个Bar.this 引用同一个对象,Bartender 会被唤醒!

    【讨论】:

    • 谢谢你我做了你的改变,但这会导致在运行时抛出一个异常。 java.lang.IllegalMonitorStateException at java.lang.Object.notify(Native Method) 知道是什么原因造成的吗?
    • @James 我错误地忘记了一些东西。我已经修好了。
    猜你喜欢
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多