为什么等待和通知功能无法在同一类锁上正常工作?

请查看下面的代码以了解等待和通知功能及其输出。

输出:

Thread-1
Thread-2
Thread-2 after notify


预期结果:

Thread-1
Thread-2
Thread-2 after notify
Thread-1 after wait


码:

public class WaitAndNotify1 {
    public static void main(String[] args) {
        Thread t1=new Thread(new Runnable(){
            @Override
            public void run(){
                System.out.println("Thread-1");
                try {
                    synchronized (this) {
                        wait();
                        System.out.println("Thread-1 after wait");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2=new Thread(new Runnable(){
            @Override
            public void run(){
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread-2");
                synchronized (this) {
                    notify();
                    System.out.println("Thread-2 after notify");
                }
            }
        });
        t1.start();
        t2.start();
    }
}

最佳答案

您正在使用匿名内部类中的this-因此它引用了该匿名内部类的实例。有两个不同的实例(具有不同的匿名内部类),因此您要在与调用wait()的对象不同的对象上调用notify()

目前,您实际上没有要同步的WaitAndNotify1实例。您可以将代码移至实例方法,然后使用WaitAndNotify1.this引用实例-此时,您将获得预期的输出:

public class WaitAndNotify1 {
    public static void main(String[] args) {
        new WaitAndNotify1().test();
    }

    public void test() {
        Thread t1=new Thread(new Runnable(){
            @Override
            public void run(){
                System.out.println("Thread-1");
                try {
                    synchronized (WaitAndNotify1.this) {
                        WaitAndNotify1.this.wait();
                        System.out.println("Thread-1 after wait");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2=new Thread(new Runnable(){
            @Override
            public void run(){
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread-2");
                synchronized (WaitAndNotify1.this) {
                    WaitAndNotify1.this.notify();
                    System.out.println("Thread-2 after notify");
                }
            }
        });
        t1.start();
        t2.start();
    }
}

关于java - 为什么在同一类锁上等待和通知功能无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37672929/

10-10 03:39