【问题标题】:Java synchronization is doing auto notify on exit ? Is this expected?Java 同步是在退出时自动通知吗?这是预期的吗?
【发布时间】:2013-06-06 06:22:16
【问题描述】:

Java 问题:

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

我已经测试过了,它看起来像 1. 当执行超出同步块时,它会自动 notifyAll() 2. 方法本身同步的时候,返回时会自动notify()。(不是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]:检查锁是否可用...
    [2]:获得锁!
    [1] : 检查锁是否可用 ...
    [2] : 正在等待锁..
    [1] : 获得了锁 !!
    [1] : Going to wait on lock..
    MyThread 正在尝试获取锁..
    MyThread 已获取锁!
    MyThread 正在退出同步块..
    MyThread 已释放锁!
    [1]:收到通知!!!
    [1]:我完成了!
    [2]:收到通知!!!
    [2]:我完成了!

标签: java


【解决方案1】:

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

此实现使用以this.isAlive 为条件的this.wait 调用循环。当一个线程终止时,this.notifyAll 方法被调用。建议应用程序不要在 Thread 实例上使用 waitnotifynotifyAll

顺便说一句,如果您使用 while 循环来检查等待条件是否按照最佳实践的要求发生了变化,这可以保护您免受此类唤醒,当然,最好只使用 @987654330 @ 无论如何都是锁。

【讨论】:

    【解决方案2】:

    您不应将Thread 对象用作锁定对象。查看更多有问题的解释Does java notify waiting threads implicitly?

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

    评论中还链接了另一个问题,现在我将使其更容易实现:who and when notify the thread.wait() when thread.join() is called?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      • 2018-04-29
      • 2012-07-16
      • 1970-01-01
      • 2011-03-26
      相关资源
      最近更新 更多