为什么执行器服务提交的任务没有异步执行任务?

问题描述 投票:0回答:1

我正在尝试在我的 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"); }}
我在终端中看到的输出:

java future executorservice completable-future java.util.concurrent
1个回答
0
投票
断点可以暂停:

    所有主题
  • 仅当前线程
默认情况下,在 IntelliJ Idea 中,断点将挂起所有线程。

如果您启动

main

(将在单独的线程上运行 
calculateAsync
),并且在调用 
calculateAsync
 后的行上设置一个断点来挂起所有线程,将会发生的情况是:

    随机地,
  1. calculateAsync
    的开头可能会出现在你到达断点之前。然而,这不太可能(线程必须分叉,这需要“一些时间”,因此更有可能在线程实际有时间启动之前命中主断点。
  2. 主断点被击中,因此所有线程都会停止(这里包括正在运行的异步线程
  3. calculateAsync
  4. 因此,由于第二个线程中的
  5. Thread.sleep
    ,除非断点未释放,否则你永远不会看到它的结束。
观察所需行为的“最简单”选项是将断点设置为“仅挂起当前线程”。如果您这样做,即使在您到达断点之后,辅助线程也将可以自由运行,因此您将看到您希望看到的内容。

但是,这并不是设置多线程测试的可靠方法。我的建议是使用 CountDownLatch

如下(p.s. 我直接在 StackOverflow 上编写代码,所以我可能会犯一些错误,请在实际运行时保持一定的容忍度):

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");
}}


© www.soinside.com 2019 - 2024. All rights reserved.