Java 什么';LinkedBlockingQueue和PriorityBlockingQueue之间的区别是什么?

Java 什么';LinkedBlockingQueue和PriorityBlockingQueue之间的区别是什么?,java,concurrency,Java,Concurrency,我需要使用两个线程创建生产者-消费者realtionshiop。一种是从磁盘上的文件中读取文本对象,然后将对象插入FIFO中的队列中,消费线程从队列中读取以处理对象。但是我不知道该使用什么类?LinkedBlockingQueue还是PriorityBlockingQueue?或者更好的 目标和宗旨: 我正在尝试实时集群tweets,但是我将tweets存档在csv文件中,而不是使用Twitter流API。因此,我试图通过从文件中读取tweet并将其放入队列,然后消费者开始从队列中读取,来模拟流

我需要使用两个线程创建生产者-消费者realtionshiop。一种是从磁盘上的文件中读取文本对象,然后将对象插入FIFO中的队列中,消费线程从队列中读取以处理对象。但是我不知道该使用什么类?LinkedBlockingQueue还是PriorityBlockingQueue?或者更好的

目标和宗旨:


我正在尝试实时集群tweets,但是我将tweets存档在csv文件中,而不是使用Twitter流API。因此,我试图通过从文件中读取tweet并将其放入队列,然后消费者开始从队列中读取,来模拟流的效果。我有非常大的csv文件,所以我更喜欢流媒体场景。因此,当我接收推文时,消费者从队列中获取推文,并实时将它们聚集在一起

您可以使用LinkedBlockingQueue,但通常使用一个打包队列和线程池的ExecutorService更简单。您可以为每个作业向it提交一个任务

PriorityBlockingQueue用于设置任务的优先级

我将查看文档中的示例


您可以使用LinkedBlockingQueue,但使用ExecutorService封装队列和线程池通常更简单。您可以为每个作业向it提交一个任务

PriorityBlockingQueue用于设置任务的优先级

我将查看文档中的示例


优先级阻止队列在您的情况下似乎没有意义,因为您只想按原始顺序处理消息

如果确实希望自己处理队列,可以使用有界LinkedBlockingQueue:

//example with a limit of 100,000 messages being in the queue at any one time
private static final BlockingQueue<Message> queue =
                                      new LinkedBlockingQueue<> (100_000);
在消费者方面:

Message msg = queue.take(); //blocks until there is a message

Peter Lawrey的替代方案包括:

private static final ExecutorService executor = Executors.newFixedThreadPool(10);
在您的制作人中:

final Message msg = getMessage();
Runnable task = new Runnable() {
    public void run() { process(msg); }
}
executor.submit(task);
自从你的制作人创建了它(任务),就没有消费者了


注意:在threadpool示例中,我使用了10个线程的大小,这是基于假设
进程
方法主要受CPU限制,并且大约有10个处理器。实际上:

  • 如果是这种情况(CPU受限),您将使用
    Runtime.getRuntime().availableProcessors()
    获取处理器数量,而不是harcoded数量
  • 如果没有(I/O限制),您将使用更多线程-最佳线程数很难事先估计,您需要使用不同的线程数来分析应用程序,以找到最佳值

PriorityBlockingQueue在您的情况下似乎没有意义,因为您只想按原始顺序处理消息

如果确实希望自己处理队列,可以使用有界LinkedBlockingQueue:

//example with a limit of 100,000 messages being in the queue at any one time
private static final BlockingQueue<Message> queue =
                                      new LinkedBlockingQueue<> (100_000);
在消费者方面:

Message msg = queue.take(); //blocks until there is a message

Peter Lawrey的替代方案包括:

private static final ExecutorService executor = Executors.newFixedThreadPool(10);
在您的制作人中:

final Message msg = getMessage();
Runnable task = new Runnable() {
    public void run() { process(msg); }
}
executor.submit(task);
自从你的制作人创建了它(任务),就没有消费者了


注意:在threadpool示例中,我使用了10个线程的大小,这是基于假设
进程
方法主要受CPU限制,并且大约有10个处理器。实际上:

  • 如果是这种情况(CPU受限),您将使用
    Runtime.getRuntime().availableProcessors()
    获取处理器数量,而不是harcoded数量
  • 如果没有(I/O限制),您将使用更多线程-最佳线程数很难事先估计,您需要使用不同的线程数来分析应用程序,以找到最佳值


关于您的具体要求,您没有告诉我们足够的信息,无法回答您的问题。如果您不需要按优先级对队列中的项目重新排序,那么
LinkedBlockingQueue
就足够了。您阅读了相应的Javadoc吗?这两种实现是相当具体和不同的。哪些特性似乎最适合您的用例?如果您需要优先级,请使用实现它的特性。如果您需要FIFO,请使用另一个。这并不难。@Stephan:标题中的问题可以通过阅读文档轻松回答,所以肯定不止这些。感谢您的编辑,但我认为答案仍然是一样的:如果您需要重新排序项目,请给我们一个优先级队列,如果你不知道的话,你还没有告诉我们足够的关于你的具体要求来回答你的问题。如果您不需要按优先级对队列中的项目重新排序,那么
LinkedBlockingQueue
就足够了。您阅读了相应的Javadoc吗?这两种实现是相当具体和不同的。哪些特性似乎最适合您的用例?如果您需要优先级,请使用实现它的特性。如果您需要FIFO,请使用另一个。这并不难。@Stephan:标题中的问题很容易通过阅读文档来回答,所以肯定不止这些。感谢您的编辑,但我认为答案仍然是一样的:如果您需要对项目重新排序,我们会提供一个优先级队列,如果您不需要,我们会提供一个普通的阻塞队列。哪个ExecutorService会这样做?你能用一些示例代码编辑你的答案吗?你可以使用其中的任何一个。您没有足够的详细信息来选择一个或另一个。如果是ExecutorService,您无法确定要放入队列的消息的顺序。为了确保ordering ArrayBlockingQueue必须在Constructor中的fair参数设置为true的情况下使用,哪个ExecutorService会这样做?你能用一些示例代码编辑你的答案吗?你可以使用其中的任何一个。您没有足够的详细信息来选择一个或另一个。如果是ExecutorService,您无法确定要放入队列的消息的顺序。为了确保ordering ArrayBlockingQueue必须在构造函数中将fair参数设置为true的情况下使用,我认为创建几个使用者从某个队列读取数据(在您的情况下,限制为100_000)比创建一个100_000的池要便宜_