The*_*ice 7 java concurrency multithreading asynchronous java-8
语境:我读过这个SO线程讨论CompletableFuture和线程之间的差异。
但我试图了解何时应该使用 new Thread() 而不是 runAsync()。
我知道 runAsyn() 对于短/一次性并行任务更有效,因为我的程序可能会避免创建全新线程的开销,但我是否也应该考虑它用于长时间运行的操作?
在考虑使用一个而不是另一个之前,我应该了解哪些因素?
谢谢大家。
使用低级并发 API(例如 Thread)和其他 API 之间的区别不仅在于您想要完成的工作类型,还在于编程模型以及它们如何轻松地配置环境任务运行。
一般情况下,建议使用更高级别的 API,例如CompletableFuture
不要直接使用Thread
s。
我知道 runAsyn() 对于短/一次性并行任务更有效
好吧,也许,假设您调用runAsync
,指望它使用 fork-join 池。该runAsync
方法重载了一种方法,该方法允许指定java.util.concurrent.Executor
执行异步任务的方法。
使用ExecutorService
对线程池的更多控制和使用CompletableFuture.runAsync
或CompletableFuture.supplyAsync
使用指定的执行程序服务(或不使用)通常比Thread
直接创建和运行对象更受欢迎。
没有什么特别赞成或反对将 CompletableFuture API 用于长时间运行的任务。但是选择使用Thread
s 也有其他含义,其中包括:
CompletableFuture
为响应式编程提供了更好的 API,而无需强制我们编写显式的同步代码。(直接使用线程时我们没有得到这个)Future
接口(由实施CompletableFuture
)给出的其它附加,优势明显。因此,简而言之:您可以(并且可能应该,如果正在考虑的替代方案是Thread
API)将CompletableFuture
API 用于您的长时间运行的任务。为了更好地控制线程池,您可以将其与执行程序服务结合使用。
主要区别在于CompletableFuture
默认情况下在ForkJoinPool.commonPool
. 但是,如果您创建自己的线程并启动它,它将作为单个线程执行,而不是在线程池上执行。此外,如果您想按顺序执行某些任务,但是asynchronously
. 然后你可以像下面这样做。
CompletableFuture.runAsync(() -> {
System.out.println("On first task");
System.out.println("Thread : " + Thread.currentThread());
}).thenRun(() -> {
System.out.println("On second task");
});
Run Code Online (Sandbox Code Playgroud)
输出:
On first task
Thread : Thread[ForkJoinPool.commonPool-worker-1,5,main]
On second task
Run Code Online (Sandbox Code Playgroud)
如果您运行上面的代码,您可以看到CompletableFuture
正在使用哪个池。
注意:Threads 是
ForkJoinPool.commonPool
.