为什么在同一个类锁

时间:2016-06-07 07:21:05

标签: java multithreading java-threads

为什么在相同的类锁上等待并通知函数不能正常工作?

请参阅以下检查代码,了解等待和通知功能及其输出。

输出:

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

1 个答案:

答案 0 :(得分:5)

您正在使用来自匿名内部类的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();
    }
}