【发布时间】:2021-07-18 03:59:51
【问题描述】:
根据其定义,队列应该是一种先进先出的结构。当我们让它阻塞时,这意味着当队列的大小等于队列大小的 MAX_LIMIT 时,几个线程可能会在添加新元素时被阻塞。现在如果一个元素从队列中出队,我们如何确保第一次等待的线程能够执行。
【问题讨论】:
标签: java multithreading concurrency queue
根据其定义,队列应该是一种先进先出的结构。当我们让它阻塞时,这意味着当队列的大小等于队列大小的 MAX_LIMIT 时,几个线程可能会在添加新元素时被阻塞。现在如果一个元素从队列中出队,我们如何确保第一次等待的线程能够执行。
【问题讨论】:
标签: java multithreading concurrency queue
如果您阅读了特定实现的文档,您将例如查找:
此类支持可选的公平策略,用于对等待的生产者和消费者线程进行排序。默认情况下,不保证此排序。但是,公平性设置为
true的队列以 FIFO 顺序授予线程访问权限。公平通常会降低吞吐量,但会降低可变性并避免饥饿。
没有可用的公平保证。
此类支持可选的公平策略,用于对等待的生产者和消费者线程进行排序。默认情况下,不保证此排序。但是,公平性设置为
true的队列会按照 FIFO 顺序授予线程访问权限。
【讨论】:
请参阅@Andreas' answer,了解常规队列类如何处理此问题的摘要。
但我将建议另一种方法/方式来看待这个问题。
您提出了一个线程阻塞的场景,因为它们无法添加到队列中。如果发生这种情况,那么从性能角度来看,您最大的问题是被阻塞线程使用/持有的资源和锁。
一般来说,有两种可能的原因:
您在添加和删除队列条目的速率之间存在短期不平衡。这可以通过简单地增加队列边界来解决。
您在添加和删除队列条目的速率之间存在长期不平衡。这只能通过添加更多的消费者线程和/或删除工作线程来解决。
重点是如果可以让线程不需要阻塞,就不用担心阻塞线程的公平性了。
另一个问题是公平是否真的很重要。以严格公平的方式将条目添加到队列中真的很重要吗?是否影响应用程序的正确性? (用户能否知道他们的请求何时被搁置……或超过其他用户的请求?)
(我可以想象一些需要严格公平的场景。但它们只是极少数。)
如果要求严格的公平,那么在将请求添加到队列之前处理请求又会怎样。 那个也需要公平吗?因为 JVM 和操作系统不提供线程调度公平的任何保证。
基本上,使请求处理完全公平是一个棘手的问题。所以对于大多数场景来说,实现 FIFO 队列提交的严格公平是没有意义的。
【讨论】: