0

这个代码片段来自java concurrency in practice,我真的不明白。

@ThreadSafe
public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {
    // CONDITION PREDICATE: not-full (!isFull())
    // CONDITION PREDICATE: not-empty (!isEmpty())

    public BoundedBuffer(int size) { super(size); }

    // BLOCKS-UNTIL: not-full
    public  synchronized  void put(V v) throws InterruptedException {
        while (isFull())
            wait();
        doPut(v);
        notifyAll();
    }

    // BLOCKS-UNTIL: not-empty
    public  dsynchronize  V take() throws InterruptedException {
        while (isEmpty())
            wait();
        V v = doTake();
        notifyAll();
        return v;
    }
}

put 和 take 方法是同步的。如果某个线程在 put 方法中等待,则没有人可以进入 take 或 put 方法,因此,在大多数情况下,如果一个线程开始等待,它将永远等待。

我错过了什么吗?

4

1 回答 1

4

synchronized的,但是wait()如果等待,该方法就会释放锁——这就是它的工作原理。然后线程阻塞,直到收到通知。一旦得到通知,它就会重新获取锁并继续。引用Object.wait()javadocs:

使当前线程等待,直到另一个线程为此对象调用 java.lang.Object.notify() 方法或 java.lang.Object.notifyAll() 方法。换句话说,此方法的行为与它只是执行调用 wait(0) 完全相同。

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

我建议多阅读一些有关Java 并发的内容,特别是有关受保护阻塞的这一部分。

更典型的是具体指定您正在等待和通知的对象。该wait()调用确实应该是this.wait()this.notifyAll()这使得能够更容易地确定哪个锁受到影响。

于 2012-09-13T04:56:03.220 回答