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){