【问题标题】:Java LinkedBlockingQueue RealizationJava LinkedBlockingQueue 实现
【发布时间】:2011-03-30 05:07:07
【问题描述】:

看了JDKLinkedBlockingQueue类,迷路了。

public void put(E e) throws InterruptedException {
    if (e == null) throw new NullPointerException();
    // Note: convention in all put/take/etc is to preset local var
    // holding count negative to indicate failure unless set.
    int c = -1;
    final ReentrantLock putLock = this.putLock;
    final AtomicInteger count = this.count;
    putLock.lockInterruptibly();
    try {
        /*
         * Note that count is used in wait guard even though it is
         * not protected by lock. This works because count can
         * only decrease at this point (all other puts are shut
         * out by lock), and we (or some other waiting put) are
         * signalled if it ever changes from
         * capacity. Similarly for all other uses of count in
         * other wait guards.
         */
        while (count.get() == capacity) { 
                notFull.await();
        }
        enqueue(e);
        c = count.getAndIncrement();
        if (c + 1 < capacity)
            notFull.signal();
    } finally {
        putLock.unlock();
    }
    if (c == 0)
        signalNotEmpty();
}

请看最后一个条件(c == 0),我想应该是(c != 0)

谢谢,我明白了。 但是我还有一个关于 LinkedBlockingQueue 实现的问题。 enqueue 和 dequeue 函数不能相交。我看到当 put() 被执行时, take() 也可以被执行。而且头尾对象没有同步,入队和出队可以在不同的线程中同时工作。它不是线程安全的,可能会发生故障。

【问题讨论】:

  • 至于编辑:你可能在拍摄中错过了while (count.get() == 0) notEmpty.await();
  • 如果您有新问题,请提出一个新问题 -- 现有问题刚刚被更改,这真的很令人困惑。

标签: java collections


【解决方案1】:

不,目的是在队列从 0 变为 1 时发出信号(即第一次将某些内容添加到空队列中)。将项目添加到已经有项目的队列时,您不需要“发出非空信号”。 (您会注意到只有当队列计数 == 0 时才会等待 notEmpty 条件。

【讨论】:

    【解决方案2】:

    您不需要在每次看跌时都发出信号。即,如果支票是c != 0,那么每次你放东西时,你都会发出信号表明你不是空的,但是如果你以前不是空的,没有人会发出信号。所以c == 0 确保您仅在队列从空状态变为非空状态时发出信号。

    比较的是 c == 0,而不是 c == 1,因为对 count 的调用是“getAndIncrement”,所以将返回 0,然后 count 将递增。

    编辑:显然有人在我之前就已经做到了:\

    【讨论】:

      【解决方案3】:

      c 是递增前的count

      c = count.getAndIncrement();
      

      所以,这个条件的意思是“如果队列是空的,通知其他人现在它不是空的”。

      【讨论】:

      • c = count.getAndIncrement();是的,如果队列为空,则 c 为 1,而不是 0。
      • @itun - 不,“getAndIncrement”的意思是“获取当前值(用于返回)并增加存储的值”。所以当队列为空时 c == 0。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 2013-06-08
      • 2010-11-28
      • 2017-05-02
      相关资源
      最近更新 更多