java并发实践14.6

标签 java multithreading concurrency

这段来自java并发实践的代码片段,实在是看不懂。

@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 方法,因此,在大多数情况下,如果一个线程开始等待,它将永远等待。

我是否理解错了什么?

最佳答案

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

Causes the current thread to wait until another thread invokes the java.lang.Object.notify() method or the java.lang.Object.notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

我建议您多阅读一些有关 Java concurrency 的内容。 ,特别是 guarded blocked 上的这一部分.

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

关于java并发实践14.6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12399611/

相关文章:

java - 同时处理大文本文件

c# - 终止一个线程运行我无法控制的代码

C# - 等待 WinForms 消息循环

java - 同步您正在修改的静态字段是否会使您的代码线程安全?

Java并发使电梯停在附近楼层

java - 在android中更改Imageview的大小

java - 使用compareTo(String) 按字母顺序排列数组中的字符串?

java - 我的图像在 eclipse 上运行时正确加载,但是当导出为 jar 并打开它时,根本没有图像

sql-server - 何时使用 sp_getapplock

java - 在 Java 中加载 _id MongoDB 我的对象