【问题标题】:Java Thread never receiving notifyJava 线程从不接收通知
【发布时间】:2015-05-18 21:17:48
【问题描述】:

我一直在尝试制作一个简单的 Java 线程应用程序,其中一个线程等待,另一个线程在 3 秒后将其唤醒。但是,我似乎无法让它工作,我就是不知道为什么。

public class Deadlock extends Thread {

Object lock = new Object();

public static void main(String[] args) {

    //WAITER THREAD
    Deadlock waiter = new Deadlock() {

        @Override
        public void run() {
            System.out.println("Waiter started");
            synchronized(lock) {
                try{
                    System.out.println("Waiter will wait for notify...");
                    lock.wait();
                    System.out.println("Woke up!");
                } catch(InterruptedException e) { 
                    e.printStackTrace();
                }
            }
        }//run()

    };

    //WAKER THREAD
    Deadlock waker = new Deadlock() {

        @Override
        public void run() {
            System.out.println("Waker started");
            synchronized(lock) {
                System.out.println("Waker sleeping for 3 seconds.");
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e) {}
                System.out.println("Waker notifying...");
                lock.notifyAll();
            }
        }//run

    };

    waiter.start();
    waker.start();
}

}

我得到的输出是:

服务员开始
服务员将等待通知...
唤醒者开始
Waker 睡了 3 秒。
唤醒者通知...

...并一直运行下去。我希望等待服务员线程唤醒并终止程序。

谢谢

【问题讨论】:

    标签: java multithreading wait notify


    【解决方案1】:

    您的主要问题是“锁”是类实例属性,因此两个死锁实例不共享相同的“锁”。因此,在唤醒器中调用 notifyAll() 对服务员没有影响,因为它正在等待不同的对象。最简单的解决方案是使“锁定”成为静态:

    static Object lock = new Object();
    

    ...我也会将其设为私有和最终的。

    第二个问题是,通过同时启动两个线程,您并不能真正保证等待器首先运行 - 我会在启动唤醒器之前添加一个短暂的延迟。

    【讨论】:

    • 对了,java.util.concurrent包提供了更好的并发控制方式,值得一看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    • 2020-08-31
    • 2013-12-05
    相关资源
    最近更新 更多