Java 等待阻塞队列已满
我正在寻找一种同步多个异步操作的方法。我想使用一个与我的操作相同大小的阻塞队列,但谁能等到队列已满 我在寻找像反向阻塞队列这样的东西 最后,我需要收集每个线程的结果。 AsyncHandler是固定的,它已经是一个ThreadExecutor底层,我无法启动新线程Java 等待阻塞队列已满,java,multithreading,synchronization,blockingqueue,Java,Multithreading,Synchronization,Blockingqueue,我正在寻找一种同步多个异步操作的方法。我想使用一个与我的操作相同大小的阻塞队列,但谁能等到队列已满 我在寻找像反向阻塞队列这样的东西 最后,我需要收集每个线程的结果。 AsyncHandler是固定的,它已经是一个ThreadExecutor底层,我无法启动新线程 //3 Times makeAsync(new AsyncHandler() { onSuccess() { .. queue.put(result) } onFailure() {
//3 Times
makeAsync(new AsyncHandler() {
onSuccess() {
..
queue.put(result)
}
onFailure() {
..
}
});
//Blocking till the Queue is full
List<Results> = queue.takeAll()
//三次
makeAsync(新的AsyncHandler(){
onSuccess(){
..
queue.put(结果)
}
onFailure(){
..
}
});
//阻塞直到队列已满
List=queue.takeAll()
附加问题:我需要一种方法来在我的一个请求失败时结束等待我从来没有需要做这种事情,但是您可能会从各种线程中使用or来获得一些运气。我从来没有需要做这种事情,但是您可能会从各种线程中使用or来获得一些运气。如果您使用的是Java 8,请执行以下操作:
- 每次调用
,创建一个makeAsync
实例,使其可供CompletableFuture
使用,并让调用者保留一个引用,比如在列表中asynchHandler
- 当异步任务正常完成时,让它对其
实例调用CompletableFuture
complete(result)
- 当异步任务完成时出现错误,让它对其
实例调用CompletableFuture
completeeexceptionaly(exception)
- 启动所有异步任务后,让调用方调用
。不幸的是,这需要一个数组,而不是一个列表,因此必须进行转换。如果任何一个任务完成时出现错误,CompletableFuture.allOf(cfArray.join()
调用将引发异常。否则,您可以通过调用各个join()
实例的CompletableFuture
方法来收集结果get()
如果您没有Java8,您将不得不使用自己的机制。将倒计时锁存器初始化为要触发的异步任务数。让每个异步任务将其结果(或异常,或指示失败的其他方式)存储到线程安全的数据结构中,然后减少锁存(“倒计时”)。让调用方等待闩锁达到零,然后收集结果和错误。这并不十分困难,但您必须确定存储有效结果以及记录是否发生错误的方法,并手动维护计数。如果您使用的是Java 8,请执行以下操作:
- 每次调用
,创建一个makeAsync
实例,使其可供CompletableFuture
使用,并让调用者保留一个引用,比如在列表中asynchHandler
- 当异步任务正常完成时,让它对其
实例调用CompletableFuture
complete(result)
- 当异步任务完成时出现错误,让它对其
实例调用CompletableFuture
completeeexceptionaly(exception)
- 启动所有异步任务后,让调用方调用
。不幸的是,这需要一个数组,而不是一个列表,因此必须进行转换。如果任何一个任务完成时出现错误,CompletableFuture.allOf(cfArray.join()
调用将引发异常。否则,您可以通过调用各个join()
实例的CompletableFuture
方法来收集结果get()
如果您没有Java8,您将不得不使用自己的机制。将倒计时锁存器初始化为要触发的异步任务数。让每个异步任务将其结果(或异常,或指示失败的其他方式)存储到线程安全的数据结构中,然后减少锁存(“倒计时”)。让调用方等待闩锁达到零,然后收集结果和错误。这并不十分困难,但您必须确定存储有效结果以及记录是否发生错误的方法,并手动维护计数。如果您可以修改methodAsync(),然后,每次将一些元素放入队列并让主线程等待这样一个CountDownLatch之后,就可以简单地使用CountDownLatch 如果不幸无法修改methodAsync(),则只需包装队列并为其提供倒计时闩锁,然后重写add()方法以倒计时此闩锁。主要方法就是等待它完成
如上所述,您的程序结构似乎没有很好的组织。如果您可以修改methodAsync(),那么每次将一些元素放入队列并让主线程等待这样的倒计时闩锁后,就可以使用倒计时闩锁 如果不幸无法修改methodAsync(),则只需包装队列并为其提供倒计时闩锁,然后重写add()方法以倒计时此闩锁。主要方法就是等待它完成 如上所述,您的程序结构似乎没有很好地组织。您用什么描述
//Blocking till the Queue is full
List<Results> results = queue.takeAll();
列表结果=新的ArrayList(容量);
队列.拖入(结果、容量);
而(result.size()您用
//Blocking till the Queue is full
List<Results> results = queue.takeAll();
列表结果=新的ArrayList(容量);
队列.拖入(结果、容量);
while(result.size())感谢您的回答,这些工具非常适合,但我需要在所有任务完成后收集结果。感谢您的回答,这些工具非常适合,但我需要在所有任务完成后收集结果。
List<Results> results = new ArrayList<>(capacity);
queue.drainTo(results, capacity);
while(result.size()<capacity)
queue.drainTo(results, capacity-result.size());