Java CompletableFuture.complete()块
我在java中使用CompletableFuture时遇到了一个问题。 我有两个select请求,它们是在从服务器接收响应时填写的 在连接线程(线程1)(使用reactor)中,我使用: 在其他线程(线程2)中,我使用: 我的情况是,系统打印出“接收所有未来”,但调用Java CompletableFuture.complete()块,java,multithreading,future,reactor,completable-future,Java,Multithreading,Future,Reactor,Completable Future,我在java中使用CompletableFuture时遇到了一个问题。 我有两个select请求,它们是在从服务器接收响应时填写的 在连接线程(线程1)(使用reactor)中,我使用: 在其他线程(线程2)中,我使用: 我的情况是,系统打印出“接收所有未来”,但调用future.complete(结果)时线程1被阻塞它无法退出该命令。 如果在线程2中,我使用CompletableFuture.allOf(allOfSelect.get(),线程1将正确运行。但是使用CompletableFut
future.complete(结果)时线程1被阻塞代码>它无法退出该命令。
如果在线程2中,我使用CompletableFuture.allOf(allOfSelect.get()
,线程1将正确运行。但是使用CompletableFuture.get()
会降低性能,所以我想使用CompletableFuture.whenComplete()
有人能帮我解释一下阻塞的原因吗
谢谢 调用complete
会触发所有相关CompletionStage
s
因此,如果您以前已在完成时向注册了BiConsumer
,complete
将在其调用线程中调用它。在您的情况下,当完成时,BiConsumer
传递给时,对complete
的调用将返回。这在中进行了描述
为非异步方法的依赖完成提供的操作可能是
由完成当前任务的线程执行
CompletableFuture
,或由完成方法的任何其他调用方执行
(另一个调用者的情况正好相反,如果目标CompletableFuture
已经完成,则调用whenComplete
的线程实际上会应用BiConsumer
。)
下面是一个小程序来说明这种行为:
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = new CompletableFuture<String>();
future.whenComplete((r, t) -> {
System.out.println("before sleep, executed in thread " + Thread.currentThread());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after sleep, executed in thread " + Thread.currentThread());
});
System.out.println(Thread.currentThread());
future.complete("completed");
System.out.println("done");
}
显示在主线程中应用了BiConsumer
,即调用complete
的线程
您可以使用强制在单独的线程中执行BiConsumer
[…]使用此阶段的默认值执行给定操作
此阶段完成时的异步执行功能
比如说,
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = new CompletableFuture<String>();
CompletableFuture<?> done = future.whenCompleteAsync((r, t) -> {
System.out.println("before sleep, executed in thread " + Thread.currentThread());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after sleep, executed in thread " + Thread.currentThread());
});
System.out.println(Thread.currentThread());
future.complete("completed");
System.out.println("done");
done.get();
}
显示BiConsumer
已在单独的线程中应用。非常感谢。你对线程的解释很清楚。在我第一次使用CompletableFuture时,我只使用它来调用从客户端到服务器的单个请求(如SELECT、UPDATE等),因此它完全按照我的预期运行(客户端等待响应并填充未来)。但现在,我在处理事务时遇到了一个问题,因为它有阶段。我想在所有SELECT done之后立即将future作为CompletableFuture返回,但是只有在其他执行(更新、删除)有结果时,future才会被填充。你能给我一个解决方案来处理连锁店的事情吗。非常感谢!我想按顺序做一些事情,比如:1。选择->CompletableFuture 2。PREPARE->CompletableFuture(也执行返回CompletableFutures的其他调用)。3.COMMIT->CompletableFuture,事务必须在注册时立即返回给调用方。非常感谢!
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = new CompletableFuture<String>();
future.whenComplete((r, t) -> {
System.out.println("before sleep, executed in thread " + Thread.currentThread());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after sleep, executed in thread " + Thread.currentThread());
});
System.out.println(Thread.currentThread());
future.complete("completed");
System.out.println("done");
}
Thread[main,5,main]
before sleep, executed in thread Thread[main,5,main]
after sleep, executed in thread Thread[main,5,main]
done
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = new CompletableFuture<String>();
CompletableFuture<?> done = future.whenCompleteAsync((r, t) -> {
System.out.println("before sleep, executed in thread " + Thread.currentThread());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after sleep, executed in thread " + Thread.currentThread());
});
System.out.println(Thread.currentThread());
future.complete("completed");
System.out.println("done");
done.get();
}
Thread[main,5,main]
done
before sleep, executed in thread Thread[ForkJoinPool.commonPool-worker-1,5,main]
after sleep, executed in thread Thread[ForkJoinPool.commonPool-worker-1,5,main]