- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
while (count.get() == capacity) {
notFull.await();
}
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
}
为什么会有一个while循环?
putLock 关闭了所有的 putting 线程。
当等待线程持有 putLock 时,没有线程可以增加“计数”。
最佳答案
await
有一个基本属性(它适用于通过 synchronized
和使用 Object.wait
的内部锁定),您必须明白:
当您调用 await
时,您将释放锁此Condition
与之相关联¹。没有办法绕过它,否则,没有人可以获取锁、满足条件并对其调用 signal
。
当您的等待线程收到信号时,它不会立即取回锁。这是不可能的,因为调用 signal
的线程仍然拥有它。相反,接收方将尝试重新获取锁,与调用 lockInterruptibly()
没有太大区别。
但是这个线程不一定是唯一一个尝试获取锁的线程。它甚至不必是第一个。在 lockInterruptibly()
发出信号并等待锁定之前,另一个线程可能已经到达 put
。因此,即使锁是公平的(通常锁不是),发出信号的线程也没有优先权。即使您为已发出信号的线程赋予优先级,也可能有多个线程因不同原因而被发出信号。
因此到达 put
的另一个线程可以在发出信号的线程之前获得锁,发现有空间,然后存储元素而无需信号。然后,当信号线程获得锁时,条件不再满足。因此,一个有信号的线程永远不能仅仅因为它收到一个信号就依赖条件的有效性,因此必须重新检查条件并在不满足时再次调用 await
。
这使得在循环中检查条件成为使用 await
的标准用法,如 the Condition
interface 中所述,以及 Object.wait
对于使用内部监视器的情况,只是为了完整性。换句话说,这甚至不特定于特定的 API。
由于无论如何都必须在循环中预先检查和重新检查条件,规范甚至允许虚假唤醒,即线程从等待操作返回但实际上没有收到信号。这可能会简化某些平台的锁实现,同时不会改变必须使用锁的方式。
¹ 重要的是要强调,当持有多个锁时,只有与条件关联的锁被释放。
关于java - 为什么 LinkedBlockingQueue 的 put() 中有一个 while 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54843122/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
我使用 LinkedBlockingQueue 为我的应用程序进行隐式同步,但如果我使用 queue.take() 或 queue.poll() ,前几个元素总是以某种方式从队列中获取后丢失。我已经检
我正在使用 LinkedBlockingQueue 在线程之间共享一些对象。问题是这个队列中可能有一些重复项。我尝试过这个解决方案: SortedSet set = new TreeSet(new M
如果我运行以下程序,JVM 在执行后不会终止。但是,如果我取消代码中 (//newFixedThreadPool.execute(new Producer3());) 行的注释,程序将在执行后终止。我
我有一个 LinkedBlockingQueue,我想检查队列中的元素是否按一定顺序排列,而不删除元素。我希望有一种方法可以用来查看队列中的特定位置。例如,queue.peekSpot(0) 将返回头
我正在制作一个WordCounter,它有几个线程计算不同文件中的单词。除了一个小问题,我已经把一切都搞定了。 我无法找出等待线程完成的正确方法。如果我设置 Thread.sleep 等待一小段时间,
我想知道为什么不 LinkedBlockingQueue如果我们将底层数据结构更改为像 java.util.LinkedList 这样的非线程安全列表,是否可以工作?当我尝试时,我得到一个 NoSuc
我创建了一个类来计算同一目录中给定文件中的单词数。由于文件非常大,我决定使用多线程来实现多个文件的计数。 当按照下面指定的方式运行 DriverClass 时,它会卡在线程一。我究竟做错了什么?当我迭
我有一个非常基本的线程池代码。它调用位于 linkedblockingqueue 中的工作对象池。该代码只是通过回收工作对象来打印出输入数据。 我发现与以下内容一致的死锁/卡住: public cla
我的情况是单个生产者和单个消费者处理对象队列。队列可能为空有两种情况: 消费者处理对象的速度比生产者生成新对象的速度快(生产者在生成对象之前使用 I/O)。 生产者已完成对象的生成。 如果队列为空,我
我有 3 个线程:2 个消费者,ConsumerA 和 ConsumerB,以及一个 Producer。 我还有一个LinkedBlockingQueue队列 在 t=1 时:ConsumerA 调用
我有一个类似生产者-消费者的场景。 A 类生成 E 类型的对象。我必须将它保存在 A 类的静态数据结构中,因为消费者逻辑应该在 B 类中处理,它没有引用 A 的对象。LinkedBlockingQue
我看着 JDK LinkedBlockingQueue 类,迷路了。 public void put(E e) throws InterruptedException { if (e == n
我的问题涉及使用同步来订购我用于电梯程序的 LinkedBlockingQueue。 在该程序中,电梯应该尽可能高效地运行:从一楼到十楼的电梯将在上升过程中响应额外的停靠,即使这些停靠是在最初的 10
我需要一个 LinkedBlockingQueue 但我正在将原语传递给它。我添加到队列的数据速率约为每秒 4 毫秒或 256 个数据点。我遇到的问题是数据在开始时立即开始延迟,但随着时间的推移,JI
我在两个不同的线程之间使用 LinkedBlockingQueue。一个线程通过add添加数据,而另一个线程通过take接收数据。 我的问题是,我是否需要同步访问 add 和 take。 Linked
ArrayBlockingQueue public class ArrayBlockingQueue extends AbstractQueue implements BlockingQueu
如果尝试向阻塞队列添加超过阻塞队列剩余大小的集合,会发生什么?从我目前阅读的文档中并不清楚这一点。 LinkedBlockingQueue foo = new LinkedBlockingQ
在下面的伪代码中,我有一个 poll() 函数,该函数在主线程中永远被调用。当我在 poll() 中没有使用 sleep() 语句时,每分钟只有 2-3 个项目被另一个线程添加到队列中。这是否意味着轮
当我第一次关注LinkedBlockingQueue中的unlink方法时,我认为trail的第二个参数意味着它是第一个参数-p的下一个节点,但是我错了,因为我在remove方法中发现(Object
我是一名优秀的程序员,十分优秀!