【问题标题】:notifyAll() does not awaken threadnotifyAll() 不唤醒线程
【发布时间】:2020-03-03 16:25:09
【问题描述】:

这是来自我的程序。它会打开一个带有按钮的窗口。当我单击按钮时,它应该关闭窗口并唤醒另一个线程。但是,它永远不会唤醒另一个线程。底部的“返回线程”从不打印,我不知道为什么。

public class BrandingGui {
 public synchronized void replaceImage() throws IOException{
...
 JButton keepButton = new JButton("Keep");
 keepButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                    frame.dispose();
                    synchronized(BrandingGui.class) { 
                        //BrandingGui.this.notify();
                        notifyAll();
                    }
            }          
          });

...

   try {

           synchronized(BrandingGui.class) {    
           this.wait();
         } 
catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
System.out.println("returned to thread");
}
}

【问题讨论】:

  • 注意:notifyAll()预期唤醒任何尚未在 wait() 调用中阻塞的线程。你做了什么来确保你的代码永远不会调用this.wait()通知已经发布之后?
  • 也许与您的问题更相关:您确定 ActionListener 中的 this 与您的 this.wait() 调用中的 this 引用相同的对象吗? (我的 Java 技能有点生疏了,当它出现在匿名内部类的方法中时,我不记得 this 是什么意思了。)
  • 创建一个您调用同步、等待和通知的对象。
  • 做到了!谢谢哈尔!

标签: java multithreading swing actionlistener


【解决方案1】:

看起来你让它工作了(来自 cmets)所以这很好 - 但要解决你的 OP 代码:

当在同步时使用类级锁时,您需要在等待/通知时使用类级锁 - 而不是将实例锁(this)与类级锁混合:

public class MyClass {
    public static void main(String args[]) {

        Thread t = new Thread(new Runnable() {
            public void run() {

                synchronized (MyClass.class) {
                    MyClass.class.notifyAll();
                    System.out.println("Awake");
                }
            }
        });
        t.start();

        synchronized (MyClass.class) {
            try {            
                System.out.println("here");
                MyClass.class.wait();

            } catch (InterruptedException ie) {

            }
        }

        System.out.println("Done");
    }
}

打印:

here
Awake
Done

在您的 OP 案例中,您对 synchronized 使用类级锁,并在 notifyall 上使用 this 对象锁:

synchronized(BrandingGui.class) { 
    notifyAll();   // WRONG - this is the `this` instance lock.
}

所以在这种情况下它必须是:

synchronized(BrandingGui.class) { 
    BrandingGui.class.notifyAll();
}

【讨论】:

    猜你喜欢
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多