Java同步在退出时进行自动通知? 这是预期的吗?

Java问题:

退出同步块会自动执行notifyAll()。 这是预期的行为吗?

我已经测试了它,看起来像是1.当执行来自同步块时,它会自动执行notifyAll()2。当方法本身同步时,它会在返回时自动通知()。(而不是notifyAll())

代码:

 public class Test { public static void main(String[] args) throws InterruptedException { MyThread lock = new MyThread(); new WatingThread(lock,1).start(); new WatingThread(lock,2).start(); //above tow threads would start and then wait for a lock lock.start(); } } class MyThread extends Thread { public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("MyThread is trying to acquire the lock .."); synchronized (this) { System.out.println("MyThread has acquired the lock !!"); System.out.println("MyThread is Coming out of synch block.."); } System.out.println("MyThread has released the lock !!"); } } class WatingThread extends Thread { private Object lock; private int id; public WatingThread(Object lock, int id ) { this.lock = lock; this.id = id; } @Override public void run() { System.out.println(String.format("[%d] : Check if lock is available ...",new Object[]{id})); synchronized (lock) { System.out.println(String.format("[%d] : Acquired the lock !!",new Object[]{id})); try { System.out.println(String.format("[%d] : Going to wait on lock.. ",new Object[]{id})); lock.wait(); System.out.println(String.format("[%d] : Got notified !!!",new Object[]{id})); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(String.format("[%d] :I am done !!",new Object[]{id})); } } } 

输出:

[2]:检查锁是否可用……
[2]:获得了锁!!
[1]:检查锁是否可用……
[2]:等待锁定……
[1]:获得了锁!!
[1]:等待锁定..
MyThread试图获得锁定..
MyThread获得了锁!
MyThread正在退出同步阻止..
MyThread发布锁!
[1]:收到通知!!!
[1]:我完成了!!
[2]:收到通知!!!
[2]:我完成了!!

您发现的是java.lang.Thread在内部使用等待工具将其自身用作锁。 这在Thread.join()方法的描述中有记录(可能不是最好的地方):

此实现使用this.wait调用this.isAlive 。 当一个线程终止时,将调用this.notifyAll方法。 建议应用程序不要在Thread实例上使用waitnotifynotifyAll

顺便说一句,如果你使用while循环来检查等待的条件是否已经按照最佳实践的指示而改变,那么这样可以防止这种唤醒,当然,最好只使用一个Object作为锁定。

不应将Thread对象用作锁定对象。 查看有问题的解释java是否隐式通知等待线程? 。

广告:Jon Skeet在那里讲话 :)(这是上述链接问题答案的直接链接。)

还有另一个问题与评论相关联,现在我将使它更容易实现: 调用thread.join()时谁和何时通知thread.wait()?