简体   繁体   中英

notifyAll() does not awaken thread

This is from my program. It opens a window with a button. When I click the button, it should close the window and awaken the other thread. But, it never awakens the other thread. "returned to thread" at the bottom never prints, and I can't figure out why.

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

Looks like you got it working (from comments) so that's great - but to address your OP code:

When using the class-level lock on synchronized you need to then use the class-level lock on wait/notify - and not mix instance lock (this) with class-level lock:

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

Prints:

here
Awake
Done

In your OP case you were using the class-level lock for synchronized and using the this object lock on notifyall :

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

So in this case it must be:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM