谷粒商城—商城业务—异步和线程池(193~202)(完)"/>
谷粒商城—商城业务—异步和线程池(193~202)(完)
目录
一.异步:
二.异步编排 CompletableFuture:
三.异步编排 组合任务:
四.实际项目:
一.异步:
1)初始化 线程 的四种方式:
a:继承 Thread 类
b:实现 Runnable 接口
c:实现 Callable 接口 + FutureTask 类(可以拿到 返回结果,可以处理异常)
d:线程池:
-1.实际开发中,以上三种,线程启动的方式都不使用,将所有的多线程一步任务,都交给线程池执行。
-2.整个系统中,线程池只有一两个。每个异步任务,直接提交给 线程池,让他自己去执行就行。
-3.代码示例:
/*** @Author zhangsan* @Date 2021/4/7 10:31 上午* @Version 1.0*/
public class ThreadTest01 {public static ExecutorService executorService = Executors.newFixedThreadPool(10);public static void main(String[] args) throws Exception {executorService.execute(new Thread02());}
}class Thread02 implements Runnable {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}
}
e:四种方式区别:
-1. 1.2 不能获取返回值,3能获取返回值。
-2. 1.2.3 都不能 控制资源,4 能控制资源。
2)线程池详解:
a:线程池的创建:
-1.参数解释:(七大参数)
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {corePoolSize –核心线程数,创建好以后,一直存在,除非设置了allowCoreThreadTimeOut
maximumPoolSize –池中允许的最大线程数
keepAliveTime –存活时间,当线程数大于核心数时,只要线程空闲大于指定的 存活时间,就会释放空闲(核心线程之外的)的线程。
unit – keepAliveTime 参数的时间单位
workQueue –阻塞队列,如果任务有很多,就会将 目前多的任务,放在队列里面,只要有线程空闲,就回去队列取出新的任务执行。
threadFactory –创建线程的工厂(默认)
handler –如果队列满了,按照 我们指定的 拒绝策略 拒绝执行任务。
-2.创建代码:
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,20,20,TimeUnit.SECONDS,new LinkedBlockingDeque<>(100),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
b:线程池的工作顺序:
-1.线程池创建,准备好 核心数量的 核心线程,准备接受任务。
-2.core 满了,就将 再进来的 任务 放入到 阻塞队列中。空闲的 core 就会自己去 阻塞队列 获取任务执行。
-3.阻塞队列满了,就直接开新的线程,最大能开到 max 指定的数量。
-4.max 满了,就是用 RejectedExecutionHandler 拒绝策略来拒绝任务。
-5.max 都执行完成,有很多空闲线程,在指定时间, keepAliveTime 以后,释放 mac-core 这些线程。
问:一个线程池,core 7,max 20,queue 50 ,100并发进来,如何分配?
答:7 个会立即执行,50个进入队列,然后开辟 13 个新线程,剩余 30 个,使用拒绝策略进行拒绝,都执行完毕后,超过时间会关闭新开启的13 个临时线程。
c:常见的 4 种 线程池:
//核心是0 ,都可以回收
Executors.newCachedThreadPool();//固定核心线程
Executors.newFixedThreadPool(10);//定时任务的线程池。
Executors.newScheduledThreadPool();//但线程的线程池。从队列获取任务,挨个执行
Executors.newSingleThreadExecutor();
d:开发中 为什么使用 线程池:
-1.降低资源的消耗:通过 重复利用 已经创建好的 线程,降低 线程的创建 和 销毁,带来的损耗。
-2.提高响应速度:因为 线程池中的 线程数量,没有超过线程池最大上限,有的线程处于等待分配任务的状态,当任务来时,无需创建新的线程就能执行。
-3.提高线程的可管理性:线程池 会根据 当前系统特点,对线程池内的线程进行优化处理,减少 创建和 销毁 线程,带来的系统开销。
二.异步编排 CompletableFuture:
0)业务场景:
1)创建异步对象:(CompletableFuture)
a:创建的 4 个静态方法:(无返回值 和 有返回值)
b:测试:
public class MyThreadPool {public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,20,2,TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());public static void main(String[] args) throws ExecutionException, InterruptedException {System.out.println("开始");CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {System.out.println("无返回值到异步任务");}, threadPoolExecutor);System.out.println("结束");CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("有返回值到异步任务");return 1;},threadPoolExecutor);Integer integer = integerCompletableFuture.get();System.out.println(integer);}}
2)计算完成时 回调方法:
a:4 种 静态方法:
b:使用:
public class MyThreadPool {public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,20,2,TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());public static void main(String[] args) throws ExecutionException, InterruptedException {System.out.println("开始");CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("有返回值到异步任务");return 1;}, threadPoolExecutor).whenComplete((Integer integer, Throwable throwable) -> {//可以得到 返回结果 和 异常,但是不能修改返回值:System.out.println("integer" + integer);System.out.println("throwable" + throwable);}).exceptionally((throwable) -> {//感知异常:并可以修改返回值return 3;});System.out.println("结束");}}
3)handle 方法:
a:3 种 Handler 方法:
b:使用:
public class MyThreadPool {public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,20,2,TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());public static void main(String[] args) throws ExecutionException, InterruptedException {System.out.println("开始");CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("有返回值到异步任务");return 1;}, threadPoolExecutor).handleAsync((integer, throwable) -> {System.out.println(integer);System.out.println(throwable);return 22;});Integer integer = integerCompletableFuture.get();System.out.println(integer);System.out.println("结束");}}
c:
4)线程串行化方法:
a:方法:(无结果无返回值,有结果无返回值,有结果有返回值)
b:使用:
c:
三.异步编排 组合任务:
1)两任务组合—都要完成:
a:方法:
b:代码:
public class MyThreadPool {public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,20,2,TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());public static void main(String[] args) throws Exception {System.out.println("开始");CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println("任务 1 开始");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}return 1;}, threadPoolExecutor);CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {System.out.println("任务 2 开始");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return 2;}, threadPoolExecutor);CompletableFuture<Integer> completableFuture = completableFuture1.thenCombineAsync(completableFuture2, (integer, integer2) -> {int i = integer + integer2;System.out.println(i);return i;}, threadPoolExecutor);Integer integer = completableFuture.get();System.out.println(integer + "---");System.out.println("结束");}}
2)两任务组合—一个完成:
a:方法:
b:使用:
3)多任务组合
a:方法:
b:使用:
四.实际项目:
1)未编排:(2单独查询;1查完了,查询 345)
2)编排后:(2单独查询;1查完了,查询 345)
更多推荐
谷粒商城—商城业务—异步和线程池(193~202)(完)
发布评论