![](/img/trans.png)
[英]How to resume my thread that is in a blocking process due to linkedBlockingQueue.take()
[英]Thread blocking even when LinkedBlockingQueue is empty
為了進行清楚的調查,我只有一個線程生成一個實體,一個線程使用它。 這兩部分共享LinkedBlockingQueue。 在使用實體后,線程將其轉發給其他線程以將實體保存在數據庫中。 在通過隊列插入和刪除實體的幾次迭代后,生產線程停止工作。 調試日志顯示它就像隊列阻塞插入操作一樣,即使隊列為空或有足夠的空間也是如此。
生產者代碼:
final BlockingQueue<Entity> queue = new LinkedBlockingQueue<>(8); //located in calling method
....................................................................................
do {
List<Entity> entityList = entityDatasource.getEntity();
for (Entity entity: entityList) {
try {
log.debug("Size before insert opertaion is: " + queue.size());
queue.put(entity);
log.debug("Size after insert opertaion is: " + queue.size());
} catch (InterruptedException ex) {
...
}
}
} while (atomicBool.get());
消費者代碼:
CompletableFuture<Void> queueHandler = CompletableFuture.runAsync(() -> {
do {
try {
log.debug("Queue size is: " + queue.size());
Entity entity = queue.take();
log.debug("Queue size is: " + queue.size());
storeInDb(entity);
} catch (InterruptedException ex) {
...
}
} while (atomicBool.get());
}, asyncPoolQueueHandler); //ThreadPoolTaskExecutor
List<CompletableFuture<Void>> pool = new ArrayList<>();
IntStream.range(0, 1).forEach(i -> {
pool.add(queueHandler);
});
CompletableFuture.allOf(pool.toArray(CompletableFuture[]::new));
數據庫存儲:
CompletableFuture
.supplyAsync(() -> {
return entityRep.save(entity);
}, asyncPoolDbPerformer).join(); //ThreadPoolTaskExecutor
我看到了 VisualVM,但對我來說沒有什么意外:當生產者卡住時,管道的其他部分就不動了。 我將不勝感激關於我可以如何處理我的問題的建議
問題出在錯誤的設計上。 生產者消費者不是正常的解決方案。 更合適的方法是使用按瓶頸性能縮放的同步阻塞管道。 就我而言,我受數據庫池連接性能的限制。
(dataSource->businessLogic->dataDestination) x N
其中 N 是比例
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.