7

我对这两个描述感到非常困惑:

  1. “wait方法阻塞调用线程并放弃监视器锁”
  2. “通知方法解除阻塞一个等待线程但不放弃监视器锁”

这是我的问题:

  1. 我知道Java中的每个对象都有一个锁,但是“监视器锁”是什么意思?它和对象的锁一样吗?

  2. 为什么 notify 方法需要放弃监听锁?

  3. 如果我尝试使用以下代码使对象等待:

    class simpleTask extends Thread
    {
        int waitingTime;
    
        public simpleTask(int waitingTime)
        {
            this.waitingTime = waitingTime;
        }
    
        public void run()
        {
            synchronized(this) // this is a reference of current object
            {
            try {
                this.wait(waitingTime);
            } catch (InterruptedException e) {
            // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    

和上面的第一个描述一样,是不是表示当前对象被synchronized关键字阻塞了,然后wait方法释放了锁?

4

3 回答 3

7

我知道Java中的每个对象都有一个锁,但是“监视器锁”是什么意思?它与对象的锁相同吗?

是的,它们是一样的。它们有时也被称为对象的“互斥锁”和对象的“原始锁”。(但是当有人谈论 时Lock,他们谈论的是这个 Java 接口……这是一种不同的锁定机制。)

为什么 notify 方法需要放弃监听锁?

notify方法不会放弃锁定。notify在调用返回后放弃锁定(即离开同步块或从同步方法返回)是您的代码的责任。

为什么这是必要的?因为当前正在等待该锁(在wait(...)调用中)的任何其他线程必须在调用完成之前重新获取该锁wait

他们为什么设计notify/wait这样?这样它们就可以用来实现条件变量。

和上面的第一个描述一样,是不是表示当前对象被synchronized关键字阻塞了,然后wait方法释放了锁?

那是对的。当一个线程调用时,someObject.wait()它的锁someObject被释放......然后在wait()调用返回之前(由同一个线程)重新获取。当然,与此同时,锁someObject 可能已被其他线程多次获取和释放。关键是当wait返回时,调用的线程wait将拥有锁。

于 2012-01-01T07:54:04.320 回答
0
  1. 是的,监视器锁与对象的锁相同。如果你这样做synchronized (object),那就是锁。

  2. 在您的示例中,当前对象将在等待时放弃锁,wait()调用放弃锁。在另一个线程中,notify()被调用来唤醒对象,当 wait()调用返回时它会再次持有锁。

于 2012-01-01T07:34:04.350 回答
0

监视器是一种同步构造。

等待放弃锁的原因是为了让其他线程可以获取锁,比如其他可能想要等待的线程。另外:唤醒其他线程的线程通常会在释放任何线程之前锁定,以防止竞争条件。

有关这方面的更多信息,您应该研究条件变量(即 condvars)。

于 2012-01-01T07:34:26.673 回答