异步 & 线程池(详细解释+用法) 您所在的位置:网站首页 缓存线程池 异步 & 线程池(详细解释+用法)

异步 & 线程池(详细解释+用法)

2024-07-11 23:43| 来源: 网络整理| 查看: 265

异步 & 线程池 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 大参数

在这里插入图片描述 线程池理解为银行的网点

int corePoolSize:常驻核心线程数,创建完线程以后,当有请求任务时,就会安排核心线程去完成任务,即理解为今日银行的办理窗口,当到达corePoolSize数量以后,就会放到缓存队列中。 maximumPoolSize:当任务到达corePoolSize数量以后,缓存队列中也满了,就会开启最大线程数,即理解为非今日银行的办理窗口也开始工作。 long keepAliveTime:多余空闲线程数的存活时间,当前线程数大于corePoolSize,并且等待时间大于keepAliveTime,多于线程或被销毁直到剩下corePoolSize为止。 TimeUnit unit: keepAliveTime的单位。 BlockingQueue workQueue:阻塞队列,被提交但未必执行的任务,即银行网点的候客区。 ThreadFactory threadFactory:用于创建线程池中工作线程的线程工厂,一般用默认的。 RejectedExecutionHandler、 handler:拒绝策略,当堵塞队列满了并且工作线程大于线程池的最大线程数(maximumPoolSize)。

运行流程: 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 提供了四个静态方法来创建一个异步操作 在这里插入图片描述 1、runXxx 都是没有返回结果的,supplyXxxx都是可以获取返回结果的

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 实验室设备网 版权所有