我正在尝试在我的 intellij 本地中使用异步 java。我的意图是我将从 main 方法中调用
calucalateAsync()
方法,然后将调试点放在 System.out.println("calculate async was called");
上。
理想情况下,提交给执行器服务的任务应该并发执行,但问题是在主方法执行完成之前,任务永远不会被执行。请告诉我请查看以下代码:
CompletableFuturePlay.java
public class CompletableFuturePlay {
public void calculateAsync() throws InterruptedException {
System.out.println("inside calculate async method");
Executors.newFixedThreadPool(10).submit(() -> {
System.out.println("inside the submitted task");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completed the thread");
return;
});
System.out.println("outside executores block");
}}
PlayGround.java
public class PlayGround {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletableFuturePlay completableFuturePlay = new CompletableFuturePlay();
completableFuturePlay.calculateAsync();
System.out.println("calculate async was called");
}}
我在终端中看到的输出:
如果您启动
main
(将在单独的线程上运行
calculateAsync
),并且在调用
calculateAsync
后的行上设置一个断点来挂起所有线程,将会发生的情况是:
calculateAsync
的开头可能会出现在你到达断点之前。然而,这不太可能(线程必须分叉,这需要“一些时间”,因此更有可能在线程实际有时间启动之前命中主断点。
calculateAsync
)
Thread.sleep
,除非断点未释放,否则你永远不会看到它的结束。
但是,这并不是设置多线程测试的可靠方法。我的建议是使用 CountDownLatch
public class CompletableFuturePlay {
public void calculateAsync(CountDownLatch latch, ExecutorService executor) throws InterruptedException {
System.out.println("Scheduling asynchronous execution");
executor.submit(() -> {
System.out.println("Asynchrounous execution started");
// do whatever consuming job here. You can mock it with a Thread.sleep if you want
System.out.println("Asynchronous execution ended");
latch.countDown(); //send a signal to the latch that your job is over
return;
});
System.out.println("Scheduled asynchronous execution");
}}
...然后用法:public class PlayGround {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(1); //<-- only 1 is enough
CompletableFuturePlay completableFuturePlay = new CompletableFuturePlay();
completableFuturePlay.calculateAsync(latch, executor);
System.out.println("calculate async was called");
latch.await(1, Time.MINUTES); //<-- ask the main thread to wait for the other thread to complete the execution - timeout after 1 minute
System.out.println("resume execution of main thread");
}}