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实例上使用wait
,notify
或notifyAll
。
顺便说一句,如果你使用while循环来检查等待的条件是否已经按照最佳实践的指示而改变,那么这样可以防止这种唤醒,当然,最好只使用一个Object
作为锁定。
不应将Thread
对象用作锁定对象。 查看有问题的解释java是否隐式通知等待线程? 。
广告:Jon Skeet在那里讲话 :)(这是上述链接问题答案的直接链接。)
还有另一个问题与评论相关联,现在我将使它更容易实现: 调用thread.join()时谁和何时通知thread.wait()?