Java 并发队列-一般问题(说明和用法)

Java 并发队列-一般问题(说明和用法),java,concurrency,queue,priority-queue,Java,Concurrency,Queue,Priority Queue,我很难理解并发队列的概念。我知道队列是一种先进先出(FIFO)或先到先得(FIFO)的数据结构 现在,当我们添加并发部分时,我将其解释为线程安全(如果不正确,请告诉我),事情变得有点模糊。我们所说的并发性是指各种线程添加到队列或从队列中删除(服务项目)的方式?并发是否为该操作提供了一种有序感 我将非常感谢您对并发队列功能的一般描述。类似的职位并不像我希望的那样普遍 还有并发优先级队列吗?它的用途是什么 多谢各位,有关此主题的任何简要说明或有用链接。您应该首先查看接口定义,因为它是使用队列进行线程

我很难理解并发队列的概念。我知道队列是一种先进先出(FIFO)或先到先得(FIFO)的数据结构

现在,当我们添加并发部分时,我将其解释为线程安全(如果不正确,请告诉我),事情变得有点模糊。我们所说的并发性是指各种线程添加到队列或从队列中删除(服务项目)的方式?并发是否为该操作提供了一种有序感

我将非常感谢您对并发队列功能的一般描述。类似的职位并不像我希望的那样普遍

还有并发优先级队列吗?它的用途是什么


多谢各位,有关此主题的任何简要说明或有用链接。

您应该首先查看接口定义,因为它是使用队列进行线程间通信的基石,并且包含允许生产者和消费者线程以阻塞或非阻塞方式访问队列的实用方法。这和线程安全访问是我对什么构成“并发队列”的理解(尽管我从未听说过-
BlockingQueue
这个短语仅仅存在于
java.util.concurrent
包中)

要回答问题的第二部分,您应该研究的优先级队列实现是。如果生产者线程正在生成优先级不同的任务(例如,来自“普通用户”和“高级用户”的请求),并且您希望控制消费者线程处理任务的顺序,则这可能很有用。要避免的一个可能陷阱是,由于高优先级任务的不断涌入,低优先级任务将永远无法从队列中移除。

我通过“并发”理解队列是线程安全的。这并不意味着它将是有效的。然而,我可以想象Java队列使用无锁实现,这意味着当两个线程同时尝试推送或pop时,几乎没有或根本没有惩罚。通常情况下,它们在汇编程序级别使用原子锁,以确保同一对象不能被弹出两次

我曾经写过一个无锁FIFO队列(在Delphi中),它工作得非常好。比以前使用关键部分的版本效率更高。CS版本陷入停顿,特别是当许多线程都试图访问队列时。但是,无锁版本没有瓶颈,许多线程经常访问它。

这里只留下一个我认为包含关于这里提出的一些问题的非常重要的信息


请参阅:并发集合和

阻塞队列提供的开销很小的概念有点超前。获取锁需要相当大的开销。仅凭上下文切换,我们就在谈论成千上万的指令。不仅如此,一个线程的进度将直接影响另一个线程。现在,它不像几年前那么糟糕,但与非阻塞相比,它是实质性的

BlockingQueue使用锁进行互斥

ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQUeue:是三个阻塞队列的while

ConcurrentLinkedQueue,java 1.7 LinkedTransferQueue:使用Michael和Scott的非阻塞队列算法

在中到低争用情况下(这更像是一个真实场景),非阻塞队列的性能明显优于阻塞队列


并注意到史蒂夫关于缺乏瓶颈的评论。在严重争用情况下,非阻塞算法可能会限制持续的cas尝试,而阻塞将挂起线程。然后我们看到,在严重争用情况下,阻塞队列的性能略优于非阻塞队列,但这种类型的争用无论如何都不是一种标准。

获取锁以修改线程安全队列实现只会增加很少的开销,java.util.concurrent包中的所有BlockingQueue实现都将使用至少一个锁(有些使用两个锁进行放置/获取)。如果没有锁,生产者/消费者无法执行阻塞Put/Take,批量操作(例如drainTo)也无法原子化完成。我认为Java使用无锁队列: