gpt4 book ai didi

java - 阻塞队列轮询方法在多个线程期间返回null

转载 作者:行者123 更新时间:2023-12-03 13:18:35 30 4
gpt4 key购买 nike

我们已经使用阻塞队列,执行程序框架和将来在应用程序中实现了多线程。
当用户需要任何数据时,我们都会向执行器框架提交任务,该执行器框架连接到数据库,查询数据并将数据流回。
我们有一个方法,该方法读取此数据并将其写入servletoutputstrean。


public long writeData(ServletOutputStream sos, BlockingQueue < T > blockingQueue, Future < Boolean > future) {

try (final JsonWriter writer = new JsonWriter(new OutputStreamWriter(sos, UTF_8))) {

int counter = 0;
while (true) {
Optional.ofNullable(blockingqueue.poll()).ifPresent(entityobj - > {
gson.toJson(entityobj, entityobj.getclass(), writer);
Counter++;
});



if (blockingqueue.isEmpty() && future.isDone() && future.get()) {
if (count == 0) {
Log.error("data not read properly");
}
break;
}
}
} catch (Exception e) {
log.error(e);
}
return counter;
}

当执行blockingqueue.poll()时,存储库线程有时仍未加载数据。到下一个if块出现时,阻塞队列为空,并且future完成,因此控制退出while循环。
没有响应写入流。无论如何要处理这种怪异的行为
有大量记录时不会发生这种情况。

最佳答案

When blockingqueue.poll() is being executed, there are times data is still not loaded by the repositorythread. By the time the next if block comes, blocking queue is empty and future is completed so control gets out of while loop.


您的代码中存在竞争条件,这使事情变得更加复杂:
if (blockingqueue.isEmpty() && /* race here */ future.isDone() && future.get()) {
blockingqueue.isEmpty()有可能返回true,然后作业在 future.isDone()调用发生之前完成,导致代码过早退出,队列中留有一个元素。
@Willis提到的“流末尾”对象是一个不错的选择,但是一个简单的解决方案是像下面这样重构您的代码:
boolean futureDone = future.isDone();
entity = blockingqueue.poll();
if (entity == null) {
if (futureDone) {
break;
}
} else {
// process entity
}
这样可以确保您始终从阻止队列中删除最后一个项目之前检查 future 是否已经完成,从而消除了比赛。您可能需要再进行一次民意测验,但那样很好。
顺便说一句,如果此代码确实在旋转,则应在轮询中添加某种超时以减慢它的速度,并且不占用CPU:
entity = blockingqueue.poll(50, TimeUnit.MILLISECONDS);

关于java - 阻塞队列轮询方法在多个线程期间返回null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63061559/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com