异步 & 线程池(详细解释+用法) | 您所在的位置:网站首页 › 缓存线程池 › 异步 & 线程池(详细解释+用法) |
异步 & 线程池
1. 线程回顾
1.1 初始化线程的 4 种方式
1.2 线程池的 7 大参数
1.3 常见的 4 种线程池
1.4 开发中为什么使用线程池
2 .CompletableFuture 异步编排
2.1 创建异步对象
2.2 计算完成时回调方法
2.3 handle 方法
2.4 线程串行方法
2.5 两任务组合 - 都要完成
2.6 两任务组合 - 一个完成
2.7 多任务组合
1. 线程回顾
1.1 初始化线程的 4 种方式
1、继承 Thread 2、实现 Runnable 3、实现 Callable 接口 + FutureTask(可以拿到返回结果,可以处理异常) 4、线程池 方式一和方式二 主进程无法获取线程的运算结果,不适合当前场景 方式三:主进程可以获取当前线程的运算结果,但是不利于控制服务器种的线程资源,可以导致服务器资源耗尽 方式四:通过如下两种方式初始化线程池 Executors.newFixedThreadPool(3); //或者 new ThreadPollExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit,unit,workQueue,threadFactory,handler);通过线程池性能稳定,也可以获取执行结果,并捕获异常,但是,在业务复杂情况下,一个异步调用可能会依赖另一个异步调用的执行结果 1.2 线程池的 7 大参数
运行流程: 1、线程池创建,准备好 core 数量 的核心线程,准备接受任务 2、新的任务进来,用 core准备好的空闲线程执行 core 满了,就将再进来的任务放入阻塞队列中,空闲的 core 就会自己去阻塞队列获取任务执行 阻塞队列也满了,就直接开新线程去执行,最大只能开到 max指定的数量 max 都执行好了,Max-core 数量空闲的线程会在 keepAliveTime 指定的时间后自动销毁,终保持到 core大小 如果线程数开到了 max数量,还有新的任务进来,就会使用 reject 指定的拒绝策略进行处理3、所有的线程创建都是由指定的 factory 创建的 面试; 一个线程池 core 7、max 20 ,queue 50 100 并发进来怎么分配的 ? 先有 7 个能直接得到运行,接下来 50 个进入队列排队,再多开 13 个继续执行,线程70个被安排上了,剩下30个默认拒绝策略 1.3 常见的 4 种线程池 newCacheThreadPool 创建一个可缓存的线程池,如果线程池长度超过需要,可灵活回收空闲线程,若无可回收,则新建线程 newFixedThreadPool 创建一个指定长度的线程池,可控制线程最大并发数,超出的线程会再队列中等待 newScheduleThreadPool 创建一个定长线程池,支持定时及周期性任务执行 newSingleThreadExecutor 创建一个单线程化的线程池,她只会用唯一的工作线程来执行任务,保证所有任务 1.4 开发中为什么使用线程池 降低资源的消耗 通过重复利用已创建好的线程降低线程的创建和销毁带来的损耗 提高响应速度 因为线程池中的线程没有超过线程池的最大上限时,有的线程处于等待分配任务的状态,当任务来时无需创建新的线程就能执行 提高线程的客观理性 线程池会根据当前系统的特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销,无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,使用线程池进行统一分配 2 .CompletableFuture 异步编排业务场景: 查询商品详情页逻辑比较复杂,有些数据还需要远程调用,必然需要花费更多的时间 假如商品详情页的每个查询,需要如下标注时间才能完成 那么,用户需要5.5s后才能看到商品相详情页的内容,很显然是不能接受的 如果有多个线程同时完成这 6 步操作,也许只需要 1.5s 即可完成响应 2.1 创建异步对象CompletableFuture 提供了四个静态方法来创建一个异步操作 2、可以传入自定义的线程池,否则就是用默认的线程池 3、根据方法的返回类型来判断是否该方法是否有返回类型 代码实现: public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println("main....start....."); CompletableFuture completableFuture = CompletableFuture.runAsync(() -> { System.out.println("当前线程:" + Thread.currentThread().getId()); int i = 10 / 2; System.out.println("运行结果:" + i); }, executor); CompletableFuture future = CompletableFuture.supplyAsync |
CopyRight 2018-2019 实验室设备网 版权所有 |