Java:线程生产者使用者等待数据产生的最有效方法是什么 [英] Java: Thread producer consumer what is the most efficient way to wait for data to be produced

查看:108
本文介绍了Java:线程生产者使用者等待数据产生的最有效方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用BlockingQueue消费生成的数据时,等待数据出现的最有效方法是什么?

When using BlockingQueue to consume data that is produced what is the most efficient method for waiting for the data to appear?

场景:

第1步):数据列表将是添加了时间戳记的数据存储.要求这些时间戳按最接近当前时间优先级的顺序进行排序.此列表可能为空.一个线程将在其中插入时间戳. 生产

Step 1) The data list will be a data store where timestamps are added to. These timestamps are required to be ordered by closest to current time priority. This list may be empty. A thread will be inserting the timestamps into it. Produce

步骤2)我想在另一个线程中使用这里的数据,该线程将从数据中获取时间戳,并检查它们是否在当前时间之后. 消费者,然后生产

Step 2) I want to consume the data in here in another thread that will take the timestamps from data and check if they are after the current time. Consumer then Produce

第3步)(如果它们在当前时间之后),请将其发送到另一个线程进行使用和处理.一旦在此处处理了时间戳数据,请从步骤1"数据存储中删除. 使用,然后编辑原始列表.

Step 3) If they are after the current time then send them on to another thread to be consumed and processed. Once the time stamp data is processed here, remove from the Step 1 data store. Consume then edit the original list.

在下面的代码中,数据字段引用步骤1中的数据存储. 结果是当前时间之后已发送的时间戳的列表.第2步. 结果将在第3步中使用.

In the below code the data field refers to the data store in step 1. The results is the list of timestamps that have been sent that are after the current time. Step 2. The results will then be consumed step 3.

private BlockingQueue<LocalTime> data;
private final LinkedBlockingQueue<Result> results = new LinkedBlockingQueue<Result>();

@Override
public void run() {
  while (!data.isEmpty()) {
    for (LocalTime dataTime : data) {
      if (new LocalTime().isAfter(dataTime)) {
        results.put(result);
      }
    }
  }
}

问题 等待数据可能会为空的数据列表中添加数据的最有效方法是什么?专注于:

Questions What is the most efficient way to wait for data to be added in the data list that could be potentially empty? Focus on:

while (!data.isEmpty())

遵循先前的问题.

推荐答案

等待数据产生的最有效方法是什么

what is the most efficient way to wait for data to be produced

BlockingQueue具有阻止功能,该功能将挂起线程,等待队列不为空或不满.在您的情况下,您正在消耗CPU的队列上旋转.这不是首选.

The BlockingQueue has blocking functionality which will suspend threads waiting for a queue to be not empty or not full. In your case you are spinning on the queue which consume CPU. This is not preferred.

您应该使用take.

挂起将检索并删除此队列的开头,如有必要,请等待直到元素可用.

Suspending retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

BlockingQueue#take

这是等待队列中元素的最有效方法,因为挂起线程不占用cpu.将新商品放入队列后,等待的线程将被唤醒.

This will be the most efficient way to wait for elements from a queue as suspending threads consume no cpu. Once a new item is put on the queue the waiting threads will be woken.

然后,您可以使用put,它的等待语义与take相同,但前提是队列未满.

Then you can use put which has the same waiting semantics as take but only if the queue is not full.

public void run(){
   LocalTime timestamp = null;
   while((timestamp = data.take()) != null){
      ...
   }
}


根据我们的评论进行更新:


Updating based on our comments:

但是在这种情况下,时间戳是按顺序创建的, 添加.但是将来的时间戳记可能会少一些.例如.头节点是2 分钟,第二个节点是1分钟,所以第二个节点想要 首先处理

But in this case the timestamps are created in a sequential order and added. But a timestamp may be less in the future. E.g. Head node is 2 mins in future, Second node is 1 min, so the second node wants processing first

然后我的跟进:

因此您需要基于LocalDate的时间戳进行优先级排队吗?

So you need priority queuing based on the timestamp of the LocalDate?

不确定是否使用的是JodaTime或Java 8中的LocalDate.

Not sure if you are using the LocalDate from JodaTime or Java 8, let's assume the latter.

您可以使用具有相同阻塞语义的PriorityBlockingQueue.但是,BlockingQueue的优先级方面将根据定义的任何顺序使元素排队.就您而言,使用LocalDate可以使元素从最旧到最年轻或最年轻到最老排序.

You can use a PriorityBlockingQueue with the same blocking semantics. However, the priority aspect of a BlockingQueue will enqueue elements based on whatever order is defined. In your case, using the LocalDate you can have elements ordered from oldest-to-youngest or youngest-to-oldest.

BlockingQueue<LocalDate> data = new PriorityBlockingQueue<>(); 

OR INVERSE THE ORDER

BlockingQueue<LocalDate> data = new PriorityBlockingQueue<>(0, (a,b) -> b.compareTo(a));

在这种情况下,您将按自然顺序而不是排队的顺序处理LocalDate.

In this case, you will process LocalDate in their natural order and not the order in which they are enqueued.

如果您使用的是JodaTime的LocalDate,则可能需要实现自己的Comparator,类似于我的第二个示例.

If you are using JodaTime's LocalDate you may need to implement your own Comparator similar to my second example.

编辑:刚意识到您已将此标签标记为java-7.因此,您将使用JodaTime,如果JodaTime LocalDate未实现Comparable,则只需创建自己的即可.

just realized you had this tagged as java-7. So you will use the JodaTime and if the JodaTime LocalDate does not implement Comparable, just create your own.

这篇关于Java:线程生产者使用者等待数据产生的最有效方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆