java - 线程守护状态下具有自定义 ExecutorService 的 CompletableFuture.thenApplyAsync 和 CompletableFuture.runAsync 之间的区别

标签 java completable-future

我创建了一个测试类。我创建了一个静态 ExecutorService,如下所示:

private static ExecutorService service = Executors.newFixedThreadPool(4);

我用 @AfterClass 函数关闭

@AfterClass
public static void afterClass(){
    service.shutdown();
    try {
        if (!service.awaitTermination(1000, TimeUnit.MILLISECONDS)){
            service.shutdownNow();
        }
    } catch (InterruptedException e) {
        service.shutdownNow();
    }
}

现在我的问题有两个测试用例: 测试1

@Test
public void running_a_simple_asynchronous_stage(){
    CompletableFuture completableFuture = CompletableFuture.runAsync(()->{
        Assert.assertTrue(Thread.currentThread().isDaemon());
        sleepForMs(1000);
    }, service);
    Assert.assertFalse(completableFuture.isDone());
    sleepForMs(2000);
    Assert.assertTrue(completableFuture.isDone());
}

测试2

@Test
public void asynchronously_applying_a_function_on_previous_stage(){
    CompletableFuture completableFuture = CompletableFuture.completedFuture("astring").thenApplyAsync(str->{
        Assert.assertFalse(Thread.currentThread().isDaemon());
        sleepForMs(1000);
        return str.toUpperCase();
    }, service);
    Assert.assertFalse(completableFuture.isDone());
    Assert.assertNull(completableFuture.getNow(null));
    sleepForMs(2000);
    Assert.assertTrue(completableFuture.isDone());
    Assert.assertEquals("ASTRING", completableFuture.getNow(null));
}

所以我的问题是为什么在第一个测试中当前线程是守护线程而在第二个测试中不是?

最佳答案

实际上,问题在于 CompletableFuture.runAsync 内部引发的异常被忽略,并且由于测试框架依赖异常来报告测试失败,因此测试似乎通过了,但实际上并未通过。将以下内容添加到您的第一个测试中以使其抛出异常:

@Test
public void running_a_simple_asynchronous_stage() {
    CompletableFuture completableFuture = CompletableFuture.runAsync(() -> {
        Assert.assertTrue(Thread.currentThread().isDaemon());
        sleepForMs(1000);
    }, service);
    completableFuture.join();
    Assert.assertFalse(completableFuture.isDone());
    sleepForMs(2000);
    Assert.assertTrue(completableFuture.isDone());
}

请注意,completableFuture.join() 使运行 Future 的线程加入主线程,因此您将收到异常。

关于java - 线程守护状态下具有自定义 ExecutorService 的 CompletableFuture.thenApplyAsync 和 CompletableFuture.runAsync 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48704433/

相关文章:

java - 对象和类关系的含义

java - 如何执行异步计算并同时处理其他http请求?

java - 如何访问 CompletableFuture 链中所有先前的 CompletionStage 结果

java - 没有锁,是否可以快速解决多线程银行帐户问题?

java - 如何一起使用 completablefuture 和 Streams

java - 在方法完成之前未写入数据库的 JPA 更改

java - jsoup select命令操作

java - 随机数 Mathematica 与 Java

java - 像 ReSharper 这样的工具,但适用于 Java?

java - Mockito Junit 测试 - “Wanted but not invoked; However there were other interactions with this mock” 错误