per*_*kss 6 java multithreading producer-consumer blockingqueue java-7
使用BlockingQueue消耗生成的数据时,等待数据出现的最有效方法是什么?
场景:
步骤1)数据列表将是添加时间戳的数据存储.这些时间戳需要按最接近当前时间优先级排序.此列表可能为空.线程将时间戳插入其中.生产
步骤2)我想在另一个线程中使用此处的数据,该线程将从数据中获取时间戳并检查它们是否在当前时间之后.消费者然后生产
步骤3)如果它们在当前时间之后,则将它们发送到另一个线程以供消费和处理.在此处理时间戳数据后,从步骤1数据存储中删除.消费然后编辑原始列表.
在下面的代码中,数据字段引用步骤1中的数据存储.结果是在当前时间之后已发送的时间戳列表.步骤2.然后将结果消耗步骤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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题 等待数据列表中可能可能为空的数据的最有效方法是什么?专注于:
while (!data.isEmpty())
Run Code Online (Sandbox Code Playgroud)
以前的问题.
什么是等待生成数据的最有效方法
BlockingQueue具有阻塞功能,该功能将挂起等待队列不为空或未满的线程.在你的情况下,你在消耗CPU的队列上旋转.这不是优选的.
你应该用take.
挂起检索并删除此队列的头部,必要时等待,直到元素可用.
这是等待队列中元素的最有效方法,因为挂起线程不消耗cpu.将新项目放入队列后,将唤醒等待的线程.
然后你可以使用put哪个具有相同的等待语义,take但仅限于队列未满.
public void run(){
LocalTime timestamp = null;
while((timestamp = data.take()) != null){
...
}
}
Run Code Online (Sandbox Code Playgroud)
根据我们的评论更新:
但在这种情况下,时间戳按顺序创建并添加.但是未来时间戳可能会更少.例如,头节点将来是2分钟,第二节点是1分钟,所以第二个节点想要先处理
然后我的跟进:
那么你需要根据LocalDate的时间戳优先排队吗?
不确定你是使用JodaTime或Java 8中的LocalDate,让我们假设后者.
您可以使用PriorityBlockingQueue具有相同阻塞语义的a.但是,BlockingQueue的优先级方面将根据定义的顺序排列元素.在您的情况下,使用LocalDate您可以拥有从最老到最小或最小到最旧的元素.
BlockingQueue<LocalDate> data = new PriorityBlockingQueue<>();
OR INVERSE THE ORDER
BlockingQueue<LocalDate> data = new PriorityBlockingQueue<>(0, (a,b) -> b.compareTo(a));
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您将LocalDate按其自然顺序处理,而不是按照它们排队的顺序进行处理.
如果您正在使用JodaTime的LocalDate,您可能需要实现自己的Comparator类似于我的第二个示例.
编辑:刚刚意识到你有这个标记为java-7.所以你将使用JodaTime,如果JodaTime LocalDate没有实现Comparable,只需创建自己的.
| 归档时间: |
|
| 查看次数: |
708 次 |
| 最近记录: |