Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ArrayBlockingQueue:并发put和take_Java_Multithreading_Concurrency_Java.util.concurrent_Blockingqueue - Fatal编程技术网

Java ArrayBlockingQueue:并发put和take

Java ArrayBlockingQueue:并发put和take,java,multithreading,concurrency,java.util.concurrent,blockingqueue,Java,Multithreading,Concurrency,Java.util.concurrent,Blockingqueue,为什么ABQ没有使用LinkedBlockingQueue的方式实现。我们可以使用AtomicInteger来保持ABQ中的跟踪计数,也可以像LBQ一样。我们也可以将这两个锁用于ABQ。 我在这个问题上偶然发现了类似的问题 但我不明白这个问题的答案。我需要帮助理解如果我们使用两个锁实现ABQ会出现的问题。 如果有人能举一个可能失败的比赛条件的例子,那就太好了。 这个问题可以标记为重复,但我确实在寻找更具描述性的答案。那将是一个很大的帮助 我在这里粘贴了一个代码。任何人都可以显示粘贴的代码中是否存

为什么ABQ没有使用LinkedBlockingQueue的方式实现。我们可以使用AtomicInteger来保持ABQ中的跟踪计数,也可以像LBQ一样。我们也可以将这两个锁用于ABQ。 我在这个问题上偶然发现了类似的问题

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


我在这里粘贴了一个代码。任何人都可以显示粘贴的代码中是否存在可能的争用条件。

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

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

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

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

但在本例中,当您执行take()时,它只会返回head值并核化该项。然后,put()会看到LinkedBlockingQueue的容量不足。它将其项目链接到列表的尾部。没有像ArrayBlockingQueue那样覆盖内存,它必须保持连续

编辑:这是一个假设性的练习,因为代码不是这样写的。但无论如何,这里有更多细节,特别是插入和提取方法:

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

ArrayBlockingQueue已满

线程1:调用take(),获取锁A,执行它的操作,将计数减少到[capacity-1]——但还没有完全完成

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

线程1:信号未满()

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


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

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

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

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

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

但在本例中,当您执行take()时,它只会返回head值并核化该项。然后,put()会看到LinkedBlockingQueue的容量不足。它将其项目链接到列表的尾部。没有像ArrayBlockingQueue那样覆盖内存,它必须保持连续

编辑:这是一个假设性的练习,因为代码不是这样写的。但无论如何,这里有更多细节,特别是插入和提取方法:

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

ArrayBlockingQueue已满

线程1:调用take(),获取锁A,执行它的操作,将计数减少到[capacity-1]——但还没有完全完成

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

线程1:信号未满()

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


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

我做了一些研究。我得出的结论是,是的,ABQ可以以与LBQ相同的方式实施。我在粘贴箱中粘贴了一个代码来显示这一点。
不采用这种方式实现的主要原因是代码变得非常复杂,特别是因为支持迭代器和性能优势对于更复杂的实现来说并不重要。

我做了一些研究。我得出的结论是,是的,ABQ可以以与LBQ相同的方式实施。我在粘贴箱中粘贴了一个代码来显示这一点。
不采用这种方式实现的主要原因是代码变得非常复杂,特别是因为支持迭代器和性能优势对于更复杂的实现来说并不重要。

对于StackOverflow来说,这个问题几乎肯定太广泛了。您正在询问算法的设计。StackOverflow应该用于特定的编程问题:例如,“我尝试了这个…示例代码…当我期望它做Y时,它做了X。它给了什么?”使用两个锁,u可以有更好的吞吐量,就像LinkedBlockingQueue的情况一样。。生产者无需与之抗衡consumers@user3580294,不是真的!LinkedBlockingQueue不使用两个锁,因为一个锁不够:一个锁可以提供足够的安全性,但两个可以(在该算法中)提供相同级别的安全性和更好级别的性能。两个锁在阵列实现中无法提供足够的安全性,因为队列的头和尾之间的关系更复杂