Java同步在退出时进行自动通知?这是预期的吗? [英] Java synchronization is doing auto notify on exit ? Is this expected?

查看:93
本文介绍了Java同步在退出时进行自动通知?这是预期的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java问题:

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

Coming out of synchronization block automatically does notifyAll(). Is that the expected behavior?

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

I have tested it and it seems like 1. when a execution comes out of sync block , it does auto notifyAll() 2. When method itself is synchronized , it does auto notify() when it returns.( not 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]:我完成了!!

[2] : Check if lock is available ...
[2] : Acquired the lock !!
[1] : Check if lock is available ...
[2] : Going to wait on lock..
[1] : Acquired the lock !!
[1] : Going to wait on lock..
MyThread is trying to acquire the lock ..
MyThread has acquired the lock !!
MyThread is Coming out of synch block..
MyThread has released the lock !!
[1] : Got notified !!!
[1] :I am done !!
[2] : Got notified !!!
[2] :I am done !!

推荐答案

你发现的是 java.lang.Thread 使用等待设施内部使用自己作为锁。这在 Thread.join() 方法(可能不是最好的地方):

What you have discovered is that java.lang.Thread uses the wait facility internally using itself as a lock. This is documented in the description for the Thread.join() method (not the best place, probably):


此实现使用循环 this.wait 调用 this.isAlive 。当一个线程终止时,会调用this.notifyAll 方法。建议应用程序不使用等待通知 notifyAll 在线程实例上。

This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

顺便说一句,如果你使用while循环来检查等待条件是否已经改变为最好的做法是,这可以保护你免受这种唤醒,当然,最好只使用对象作为锁。

By the way, if you used a while loop for checking if the condition for waiting has changed as the best practice dictates, that would guard you against such wakeups, though, of course, it is best to just use an Object as a lock anyway.

这篇关于Java同步在退出时进行自动通知?这是预期的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆