同步、异步并发ExecutorService、异步编排Compl
2018-05-29 本文已影响0人
离别刀
80608153622.png
概念 同步、异步、并发,并行,互斥
- 同步:某一个进程在执行一个任务时候,直到该任务返回之前不能进行任何操作,只有当返回了才能进行下一步操作。
- 异步:相对于同步而言,在执行一个任务时,他不需要等待该任务完成,继续下面的事情;多线程就是异步的一个实现方式。这里启动一个新的线程在jdk1.5之后有两种办法:
1.submit,这个方法可以获取线程执行的结果,
2.execute执行任务不需要结果。 - 并发:这种在一个进程里面启动多个线程处理事务叫做并发,并发可以提高系统吞吐量,但并不能提高处理速度。因为在操作系统的底部他们还是基于时间片轮训机制分别获取时间片来处理程序。并发的目的就是为了在一个时间段内可以同时处理多个任务,在使用者看来他们是并行处理的。
- 并行:在现在多核CPU流行的今天,实际有些程序的处理已经可以并行处理,他们分别独占cpu时间片,分别处理。
- 互斥:多个线程在处理任务并且他们都赖于统一个资源的时候,在同一个时间职能有一个线程能获取该资源,这种现象叫做互斥。
服务
public class TaskService {
public String doTask1(){
try {
Thread.sleep(1000L);
System.out.println("do task 1");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "do task 1 success.";
}
public String doTask2(){
try {
Thread.sleep(2000L);
System.out.println("do task 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "do task 2 success.";
}
public String doTask3(){
try {
Thread.sleep(3000L);
System.out.println("do task 3");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "do task 3 success.";
}
}
同步调用,异步并发,异步编排
public class TaskHandler {
public void syncHandler(){
Date start= new Date();
TaskService taskService= new TaskService();
taskService.doTask1();
taskService.doTask2();
taskService.doTask3();
System.out.println(String.format("同步执行take time: %ss \r\n",(new Date().getTime()-start.getTime())/1000));
}
/**
* 启用三个线程单独处理3个任务,等处理完成之后,在处理其他事情主线程需要等待,俗称伪异步
*/
public void asyncHandler(){
Date start= new Date();
TaskService taskService= new TaskService();
ExecutorService executorService= Executors.newFixedThreadPool(3);
Callable<String>[] callableList= new Callable[]{()->taskService.doTask1(),()->taskService.doTask2(),()->taskService.doTask3()};
try {
List<Future<String>> futures= executorService.invokeAll(Arrays.asList(callableList));
List<String> results= futures.parallelStream().map(stringFuture -> {
try {
return stringFuture.get();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}).collect(Collectors.toList());
System.out.println("results :"+results);
System.out.println(String.format("异步多线程take time: %ss \r\n",(new Date().getTime()-start.getTime())/1000));
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
executorService.shutdown();
}
}
/**
* 异步编排不阻塞主线程,当任务执行完之后,通过通知返回结果
*/
public void completableFuture(){
Date start= new Date();
TaskService taskService= new TaskService();
CompletableFuture<String> completableFuture1= CompletableFuture.supplyAsync(() -> taskService.doTask1());
CompletableFuture<String> completableFuture2= CompletableFuture.supplyAsync(() -> taskService.doTask2());
CompletableFuture<String> completableFuture3= CompletableFuture.supplyAsync(() -> taskService.doTask3());
List<CompletableFuture<String>> futureList= Arrays.asList(completableFuture1,completableFuture2,completableFuture3);
CompletableFuture<Void> doneFuture= CompletableFuture.allOf(completableFuture1,completableFuture2,completableFuture3);
try {
doneFuture.whenComplete((aVoid, throwable) -> {
List results = futureList.stream().map(CompletableFuture::join).collect(Collectors.toList());
System.out.println("results :" + results);
});
System.out.println(String.format("异步编排take time: %ss ",(new Date().getTime()-start.getTime())/1000));
Thread.sleep(4000L);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TaskHandler handler= new TaskHandler();
handler.syncHandler();
handler.asyncHandler();
handler.completableFuture();
}
}
运行结果:
do task 1
do task 2
do task 3
同步执行take time: 6s
do task 1
do task 2
do task 3
results :[do task 1 success., do task 2 success., do task 3 success.]
异步多线程take time: 3s
异步编排take time: 0s
do task 1
do task 2
do task 3
results :[do task 1 success., do task 2 success., do task 3 success.]