Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 等待阻塞队列已满_Java_Multithreading_Synchronization_Blockingqueue - Fatal编程技术网

Java 等待阻塞队列已满

Java 等待阻塞队列已满,java,multithreading,synchronization,blockingqueue,Java,Multithreading,Synchronization,Blockingqueue,我正在寻找一种同步多个异步操作的方法。我想使用一个与我的操作相同大小的阻塞队列,但谁能等到队列已满 我在寻找像反向阻塞队列这样的东西 最后,我需要收集每个线程的结果。 AsyncHandler是固定的,它已经是一个ThreadExecutor底层,我无法启动新线程 //3 Times makeAsync(new AsyncHandler() { onSuccess() { .. queue.put(result) } onFailure() {

我正在寻找一种同步多个异步操作的方法。我想使用一个与我的操作相同大小的阻塞队列,但谁能等到队列已满

我在寻找像反向阻塞队列这样的东西

最后,我需要收集每个线程的结果。 AsyncHandler是固定的,它已经是一个ThreadExecutor底层,我无法启动新线程

//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());