Java并发:同步(this)=>和this.wait()和this.notify()

时间:2010-05-19 04:18:59

标签: java concurrency

感谢您帮助理解“并发示例”: http://forums.sun.com/thread.jspa?threadID=735386

Qute Start:

public synchronized void enqueue(T obj) {
    // do addition to internal list and then...
    this.notify();
}

public synchronized T dequeue() {
    while (this.size()==0) {
        this.wait(); 
    }
    return // something from the queue
}

引用结束:

我的问题是:为什么这段代码有效?

=>当我同步“public synchronized”=>之类的方法时然后我同步“对象的实例==> this”。 但是在上面的例子中:

  1. 调用“出队”我将在this

  2. 上获得“锁定/监控”
  3. 现在我处于出列方法中。由于列表为零,调用线程将为“waited

  4. 根据我的理解,我现在有一个死锁情况,因为我没有机会从一个其他线程中获取一个对象,因为“dequeue”方法还没有完成,而且dequeue“method”持有锁在this上:所以我永远不可能打电话给“enequeue”,因为我不会得到“this”锁。
  5. Backround:我有完全相同的问题:我有某种连接池(连接列表),如果检查了所有连接,则需要阻止。如果大小超过限制或为零,将List同步到阻止的正确方法是什么?

    非常感谢

2 个答案:

答案 0 :(得分:7)

请参阅:http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()

  

当前线程必须拥有此对象的监视器。线程发布   此监视器的所有权,并等待另一个线程通知   在这个对象的监视器上等待通过a唤醒的线程   调用notify方法或notifyAll方法。线程然后   等到它可以重新获得监视器的所有权并恢复   执行。

所以不,没有死锁。当调用wait()时,线程保持的监视器被释放,允许在另一个线程上调用enqueue(以及在this对象上同步的其他操作)。当通知线程时,它会在继续之前尝试再次获取监视器。

答案 1 :(得分:1)

没有死锁,因为调用wait会放弃锁定。 你可能会看看这个: Why must wait() always be in synchronized block