Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.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 CompletableFuture.anyOf(许多未来)。然后运行(runnable)只运行一次_Java_Concurrency_Java 8 - Fatal编程技术网

Java CompletableFuture.anyOf(许多未来)。然后运行(runnable)只运行一次

Java CompletableFuture.anyOf(许多未来)。然后运行(runnable)只运行一次,java,concurrency,java-8,Java,Concurrency,Java 8,我在做什么 CompletableFuture.anyOf(manyfutures).thenRun( new Runnable() { } } 但是runnable中的代码只运行一次!我希望它能运行很多次,每次期货交易完成 如何在每次期货交易完成时运行代码块?以最佳方式,这意味着这样做行不通: public static void append(final CompletableFuture[] futures, Runnable runnable) { fo

我在做什么

CompletableFuture.anyOf(manyfutures).thenRun( new Runnable() { } }
但是runnable中的代码只运行一次!我希望它能运行很多次,每次期货交易完成

如何在每次期货交易完成时运行代码块?以最佳方式,这意味着这样做行不通:

    public static void append(final CompletableFuture[] futures, Runnable runnable) {
            for (CompletableFuture future : futures) {
                    future.thenRun(runnable);
            }
    }
编辑

我使用的是一个ThreadPoolExecutor,当执行了X个可运行程序时,我想向它追加更多的工作

有没有办法倾听这一点,并在这种情况下提供更多的工作

另一种选择是,我在开始时堆叠了数千个工作,但这也不是最优的

我在做什么

... queue = new LinkedBlockingQueue<Runnable>(); 
new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, queue);
。。。队列=新的LinkedBlockingQueue();
新的ThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit.millizes,queue);
查看

返回一个新的
CompletableFuture
,当任何 给定
CompletableFutures
complete,结果相同。否则,如果 它异常地完成了,返回的
CompletableFuture
也完成了 因此,
CompletionException
将此异常作为其原因。如果 未提供
CompletableFutures
,返回不完整的
CompletableFuture

当给定的
CompletableFutures
any完成时,该方法返回。i、 第一个。一个方法不能多次返回

要在每个
CompletableFuture
之后运行操作,只需在每个
CompletableFuture
上调用
theRun
thenRunAsync

如果您有一个
列表
,并且您想要一个
可完成的未来
,即您想要将未来集合“展开”为集合的未来,您可以使用以下技巧:

private static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> futures) {
    final CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
    return allDoneFuture.thenApply(v ->
                    futures.stream().
                            map(future -> future.join()).
                            collect(toList())
    );
}
私有静态CompletableFuture序列(列表期货){
final CompletableFuture allDoneFuture=CompletableFuture.allOf(futures.toArray(新的CompletableFuture[futures.size());
返回allDoneFuture。然后应用(v->
futures.stream()。
映射(future->future.join()。
collect(toList())
);
}
摘自

查看

返回一个新的
CompletableFuture
,当任何 给定
CompletableFutures
complete,结果相同。否则,如果 它异常地完成了,返回的
CompletableFuture
也完成了 因此,
CompletionException
将此异常作为其原因。如果 未提供
CompletableFutures
,返回不完整的
CompletableFuture

当给定的
CompletableFutures
any完成时,该方法返回。i、 第一个。一个方法不能多次返回

要在每个
CompletableFuture
之后运行操作,只需在每个
CompletableFuture
上调用
theRun
thenRunAsync

如果您有一个
列表
,并且您想要一个
可完成的未来
,即您想要将未来集合“展开”为集合的未来,您可以使用以下技巧:

private static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> futures) {
    final CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
    return allDoneFuture.thenApply(v ->
                    futures.stream().
                            map(future -> future.join()).
                            collect(toList())
    );
}
私有静态CompletableFuture序列(列表期货){
final CompletableFuture allDoneFuture=CompletableFuture.allOf(futures.toArray(新的CompletableFuture[futures.size());
返回allDoneFuture。然后应用(v->
futures.stream()。
映射(future->future.join()。
collect(toList())
);
}

摘自

以下是我跟踪此问题的答案,为方便起见,此方法需要几个参数:

   /** Basically creates to-start number of futures in a while loop, while passing the index to a Lambda that is passed and that returns a Runnable which will have access to the index. See example below. **/
   public static CompletableFuture[] async(ExecutorService executorService, int start, int to, Runnable beforeAll, Lambda.R1<Runnable, Integer> onEach, Double onPercentage, Runnable onPercentageRun, Runnable afterAll) {
            CompletableFuture[] futures = new CompletableFuture[to-start];

            double        onPercentageIndex = Valid.elvis(onPercentage, 0.0) * futures.length;  // When to onPercentageRun
            AtomicBoolean percentageMet     = new AtomicBoolean ( false );
            AtomicBoolean completeMet       = new AtomicBoolean ( false );
            AtomicInteger complete          = new AtomicInteger ( 0     );

            int i = start;
            if ( i < to && beforeAll != null ) {
                    beforeAll.run();
            }
            boolean percentageSet = onPercentageIndex > 0.0 && onPercentageRun != null;
            boolean completeSet = afterAll != null;
            while( i < to ) {

                    Runnable call = onEach.call(i);
                    futures[i-start] = CompletableFuture.runAsync(

                            () -> {
                                    try {
                                            call.run();
                                    } catch (Throwable e) {
                                            $Log.info(Concurrency.class, "RunAsync: run", e);
                                    }

                                    if ( percentageSet || completeSet ) {
                                            complete.incrementAndGet();

                                            if ( percentageSet && !percentageMet.get() && complete.get() >= onPercentageIndex) {
                                                    percentageMet.set(true);

                                                    try {
                                                            onPercentageRun.run();
                                                    }
                                                    catch(Throwable e) {
                                                            $Log.info(Concurrency.class, "RunAsync: onPercentage", e);
                                                    }
                                            }

                                            if ( completeSet && !completeMet.get() && complete.get() == to ) {
                                                    completeMet.set(true); // Just for clarity, propably redundant

                                                    try {
                                                            afterAll.run();
                                                    }
                                                    catch(Throwable e) {
                                                            $Log.info(Concurrency.class, "RunAsync: onComplete", e);
                                                    }

                                            }
                                    }

                            },

                            executorService
                    );

                    ++i;
            }

            return futures;
    }
/**基本上是在while循环中创建开始数量的期货,同时将索引传递给已传递的Lambda,该Lambda返回一个将访问该索引的Runnable。见下面的例子**/
public static CompletableFuture[]异步(ExecutorService ExecutorService,int start,int to,Runnable beforeAll,Lambda.R1 onEach,Double onPercentage,Runnable onPercentageRun,Runnable afterAll){
CompletableFuture[]futures=新的CompletableFuture[开始];
double onPercentageIndex=Valid.elvis(onPercentage,0.0)*futures.length;//何时开始onPercentageRun
AtomicBoolean百分比集=新的AtomicBoolean(false);
AtomicBoolean completeMet=新的AtomicBoolean(false);
AtomicInteger complete=新的AtomicInteger(0);
int i=开始;
if(i0.0&&onPercentageRun!=null;
布尔完成集=毕竟!=空;
而(我 {
试一试{
call.run();
}捕获(可丢弃的e){
$Log.info(Concurrency.class,“RunAsync:run”,e);
}
if(百分比集| |完全集){
complete.incrementAndGet();
if(percentageSet&!percentageet.get()&&complete.get()>=onPercentageIndex){
设置百分比(真);
试一试{
onPercentageRun.run();
}
捕获(可丢弃的e){