Java CompletableFuture.thenApplyAsync和CompletableFuture.runAsync之间的差异,自定义ExecutorService处于线程deamon状态
我已经创建了一个测试类。我创建了一个静态Executor服务,如下所示:Java CompletableFuture.thenApplyAsync和CompletableFuture.runAsync之间的差异,自定义ExecutorService处于线程deamon状态,java,completable-future,Java,Completable Future,我已经创建了一个测试类。我创建了一个静态Executor服务,如下所示: private static ExecutorService service = Executors.newFixedThreadPool(4); 我用@AfterClass函数来结束它 @AfterClass public static void afterClass(){ service.shutdown(); try { if (!service.awaitTermination(1
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();
}
}
现在我的问题有两个测试用例:
Test1
@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());
}
及
Test2
@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));
}
所以我的问题是,为什么在第一个测试中,当前线程是deamon线程,而在第二个测试中不是?如果要异步运行某个后台任务,并且不想从任务返回任何内容,那么可以使用CompletableFuture.runAsync()方法。它接受一个可运行的对象并返回CompletableFuture
@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());
}
然后应用同步:-
周围没有其他线程,因此在当前主线程的上下文中调用applyasync()
@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));
}
测试1是守护进程线程,而测试2不是守护进程线程。
希望您能理解:(事实上,问题是在
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的线程加入主线程,因此您将得到异常