gpt4 book ai didi

java - ArrayBlockingQueue : concurrent put and take

转载 作者:行者123 更新时间:2023-12-02 05:40:42 24 4
gpt4 key购买 nike

为什么ABQ还没有采用LinkedBlockingQueue的方式实现。我们可以使用 AtomicInteger 来保存 ABQ 中的 Track 计数,就像 LBQ 一样。我们也可以使用两把锁进行 ABQ。我偶然发现了类似的问题。 ArrayBlockingQueue uses a single lock for insertion and removal but LinkedBlockingQueue uses 2 separate locks

但我无法理解这个问题的答案。我需要帮助来理解如果我们使用两个锁实现 ABQ 会出现的问题。如果有人能给出可能失败的竞争条件的例子,那就太好了。这个问题可以标记为重复,但我确实在寻找更具描述性的答案。这将是一个很大的帮助。

我在这里粘贴了代码http://pastebin.com/ZD1uFy7S 。任何人都可以显示粘贴的代码中是否可能存在竞争条件。

最佳答案

ArrayBlockingQueue,根据定义,当 put() 发生并且其固定数组已满时,会阻塞等待空间变得可用

可用的空间是从 take() 返回的元素。换句话说,随着时间的推移,固定数组中的元素会被重用。 put()必须将其项目写入数组中的特定位置

另一方面,LinkedBlockingQueue 是一个链表。对于本次讨论,假设您创建了一个有界队列,只是为了使其更类似于 ArrayBlockingQueue。尝试同样的事情:

当 LinkedBlockingQueue 已满时,put() 一个元素。它将等待一个元素变得可用。

但在这种情况下,当您执行 take() 时 - 它只会返回 head 值并取消该项目。然后 put() 会发现 LinkedBlockingQueue 低于容量。它将其项目链接到列表的尾部。不会像 ArrayBlockingQueue 那样覆盖内存,它必须保持连续。

编辑:这是一种假设练习,因为代码不是这样编写的。但无论如何,这里有更多细节,特别是插入和提取方法: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/ArrayBlockingQueue.java

潜在问题如果使用了 2 个锁,并且现有代码或多或少保持不变:

ArrayBlockingQueue已满

线程 1:调用 take(),获取锁 A,执行其操作,将计数递减至 [capacity-1] ——但尚未完成

线程 2:调用 put(),在 T1 仍在运行时获取锁 B,将计数增加到 [capacity],释放锁 B

线程 1:发出 notFull() 信号

线程 3:put() 开始执行,即使数组确实已满,也会覆盖一个元素,因为 ArrayBlockingQueue 使用循环增量。

这种情况不会发生在 LinkedBlockingQueue 中。

关于java - ArrayBlockingQueue : concurrent put and take,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24541672/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com