一 常见的调用方式
1.1 并发
并发:同一时刻多个线程在访问同一个资源,多个线程对一个点
例子:春运抢票、微信抢红包、电商秒杀...
1.2 同步串行
代表多任务按先后顺序执行,并且都是同一个线程来执行。
1.3 异步串行
代表多任务按先后顺序执行,并由不同的线程来执行。
1.4 并行
多项任务一起执行,之后再汇总
例子:泡方便面,电水壶烧水,一边撕调料倒入桶中
1.5 任务合并
一个任务的执行依赖于前面多个任务执行的返回值,并且这些任务可以由同一个线程执行,也可以由不同的线程执行;
1.6 多线程的4种范式
第一种 继承Thread类
第二种 实现Runnable接口
第三种 使用Callable接口
第四种 使用线程池
二 completableFuture实现
2.1 作用
CompletableFuture异步编排,CompletableFuture和FutureTask同属于Future接口的实现类,都可以获取线程的执行结果。
2.2 runAsync方法没有返回值
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo1 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
System.out.println("main begin....");
CompletableFuture<Void> completableFuture =
CompletableFuture.runAsync(()->{
System.out.println("当前线程:"+Thread.currentThread().getId());
int result = 1024;
System.out.println("result:"+result);
},executorService);
System.out.println("main over....");
}
}
2.3 supplyAsync 方法有返回值
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo2 {
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(3);
System.out.println("main begin....");
CompletableFuture<Integer> completableFuture =
CompletableFuture.supplyAsync(()->{
System.out.println("当前线程:"+Thread.currentThread().getId());
int result = 1024;
System.out.println("result:"+result);
return result;
},executorService);
//获取返回结果
Integer value = completableFuture.get();
System.out.println("main over...."+value);
}
}
2.4 计算完成时回调方法
whenComplete可以处理正常或异常的计算结果,exceptionally处理异常情况。
whenComplete 和 whenCompleteAsync 的区别:
whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。
whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。
方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)
public class Demo3 {
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(3);
System.out.println("main begin....");
CompletableFuture<Integer> completableFuture =
CompletableFuture.supplyAsync(()->{
System.out.println("当前线程:"+Thread.currentThread().getId());
int result = 10/0;
System.out.println("result:"+result);
return result;
},executorService)
.whenComplete((rs,exception)->{
System.out.println("结果:"+rs);
System.out.println(exception);
});
System.out.println("main over....");
}
}
2.5 线程串行化方法
1.thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值。
2.thenAccept方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
3henRun方法:只要上面的任务执行完成,就开始执行thenRun,只是处理完任务后,执行 thenRun的后续操作
带有Async默认是异步执行的。这里所谓的异步指的是不在当前线程内执行
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo4 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
// 线程1执行返回的结果:100
CompletableFuture<Integer> futureA =
CompletableFuture.supplyAsync(() -> {
int res = 100;
System.out.println("线程一:"+res);
return res;
});
// 线程2 获取到线程1执行的结果
CompletableFuture<Integer> futureB = futureA.thenApplyAsync((res)->{
System.out.println("线程二--"+res);
return ++res;
},executorService);
//线程3: 无法获取futureA返回结果
CompletableFuture<Void> futureC = futureA.thenRunAsync(() -> {
System.out.println("线程三....");
}, executorService);
}
}
2.6 多任务组合
allOf:等待所有任务完成
anyOf:只要有一个任务完成
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo5 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
// 线程1
CompletableFuture<Integer> futureA =
CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName()+"--begin..");
int res = 100;
System.out.println("一:"+res);
System.out.println(Thread.currentThread().getName()+"--over..");
return res;
},executorService);
// 线程2
CompletableFuture<Integer> futureB =
CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName()+"--begin..");
int res = 30;
System.out.println("二:"+res);
System.out.println(Thread.currentThread().getName()+"--over..");
return res;
},executorService);
CompletableFuture<Void> all = CompletableFuture.allOf(futureA,futureB);
all.get();
System.out.println("over....");
}
}