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

abh*_*bhi 4 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}));
        }
    }


}
Run Code Online (Sandbox Code Playgroud)

输出:

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

Mal*_*olm 5

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

此实现使用一系列this.wait调用条件this.isAlive.当一个线程终止时,该this.notifyAll方法被调用.建议应用程序无法使用wait,notifynotifyAll在线程实例.

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