异步线程使用

news/2024/12/18 16:28:59/

创建线程的几种方法:

执行完整个main方法,在后台慢慢打印。

1.2.3方式都不能获得控制资源。

4、 线程池方法,每个异步任务,提交给线程池让他自己去执行就行。

1、降低资源的消耗


通过重复利用已经创建好的线程降低线程的创建和销毁带来的损耗

2、提高响应速度


因为线程池中的线程数没有超过线程池的最大上限时,有的线程处于等待分配任务的状态,当任务来时无需创建新的线程就能执行

3、提高线程的可管理性


线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销。无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,使用线程池进行统一分配

java">public static ExecutorService service = Executors.newFixedThreadPool(10);
service.submit(new Runable01()) //有返回值
service.excute() //void

核心线程不释放。

小小面试题


异步使用的基本方法:

使用当前线程池

supplyAsync有返回值

runAsync没有返回值。

Async会创建一个新的线程,没有Async是从当前线程调用。 


出现异常

1、when可以感知,但是不可以更改

2.exception可以修改结果

3、handle方法执行后的处理。


线程床串行化。

1、then

2、accept可以感知到上一步的执行结果(返回值)

3、apply可以感知到上一步和下一步的执行结果 (返回值)

4、run仅仅处理代码。

5、Async和上面都相同

6、both表示两个任务都完成后才执行下面的语句。

7、combin合并多个。

f1,f2表示上一个的返回值

8、 Either 表示两个执行完其中一个就执行下一个


这段代码的执行流程

  1.  future01future02 异步执行
    • CompletableFuture.supplyAsync 启动任务时,会提交任务给线程池(executor),任务在后台线程执行,而主线程不会阻塞,继续向下执行代码。
    • 任务1和任务2的执行顺序取决于线程调度,无法保证谁先执行完。
  2. 主线程继续执行

    • 主线程会跳过 future01 和 future02 的异步任务代码块,直接执行 System.out.println("main.....end....") 这行代码。
  3. runAfterBothAsync 的触发

    • runAfterBothAsync 会等待 future01 和 future02 都完成后才触发。
    • 但是 runAfterBothAsync 是异步执行,它并不会阻塞主线程。
执行顺序解释

为什么 main.....end.... 出现在 "任务2结束" 和 "任务3开始..." 之间?

  • 主线程继续执行

    • 主线程先执行了 System.out.println("main.....end....")
    • 此时,future01 和 future02 仍然在执行或者已经执行完,线程池中的线程在后台完成任务。
  • 任务2结束

    • 任务2(future02)的线程在异步执行结束后,输出 "任务2结束:"
  • runAfterBothAsync 执行

    • 当 future01 和 future02 都完成时,runAfterBothAsync 的回调被触发,输出 "任务3开始..."

由于 main.....end.... 的输出是在主线程中执行的,而任务1、任务2 和 runAfterBothAsync 都是在后台线程异步执行,因此主线程和后台线程的输出会交错,具体顺序由线程调度决定。


阻塞式获取:假设代码流程

java">CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {System.out.println("任务1线程: " + Thread.currentThread().getId());System.out.println("任务1结束");return 1;
});CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {System.out.println("任务2线程: " + Thread.currentThread().getId());System.out.println("任务2结束");return "Hello";
});CompletableFuture<Double> future03 = CompletableFuture.supplyAsync(() -> {System.out.println("任务3线程: " + Thread.currentThread().getId());System.out.println("任务3结束");return 3.14;
});// 主线程调用 get() 方法
Integer result1 = future01.get();
String result2 = future02.get();
Double result3 = future03.get();System.out.println("main....end....结果1: " + result1 + ", 结果2: " + result2 + ", 结果3: " + result3);

执行流程分析

  1. 三个异步任务

    • future01future02 和 future03 会被提交到线程池的后台线程执行。
    • 它们的输出顺序是不确定的,因为它们在不同的线程中异步执行。
  2. 调用 get() 方法

    • 主线程会按照顺序依次调用 future01.get()future02.get() 和 future03.get()
    • 主线程在每个 get() 调用处会被阻塞,直到对应的 CompletableFuture 任务完成并返回结果。
    • 由于主线程是顺序阻塞的,任务执行完的结果会按照主线程的调用顺序依次获取

结果展示

任务3结束
任务1结束
任务2结束
main...end...结果: 1, Hello, 3.14
总耗时: 3010ms

注意虽然是阻塞式调用,但是 只会等待没有完成的部分。所以最后还是输出3s


http://www.ppmy.cn/news/1556158.html

相关文章

【python面向对象】304-面向对象三大特性-3.多态

三种特性&#xff1a; 封装性&#xff1a; 私有属性和私有方法把属性和方法隐藏起来&#xff0c;属性没有特殊要求都用私有属性意义&#xff1a; 以面向对象的编程思想进行项目开发封装数据属性&#xff1a;明确的区分内外&#xff0c;控制外部对隐藏的属性的操作行为(保护数据…

泷羽Sec学习笔记-zmap搭建炮台

zmap搭建炮台 zmap扫描环境&#xff1a;kali-linux 先更新软件库 sudo apt update 下载zmap sudo apt install zmap 开始扫描(需要root权限) sudo zmap -p 80 -o raw_ips.txt 代码解析&#xff1a; sudo&#xff1a;以超级用户&#xff08;管理员&#xff09;权限运行…

Zookeeper其二,zk的java和选举机制,Hadoop的高可用和联邦机制

目录 一、Zk是用java代码进行操作&#xff08;了解&#xff09; 使用java代码操作zk 3.5以下版本&#xff0c;使用的技术还是Curator 二、zk的选举机制 三、Hadoop集群的高可用&#xff08;HA&#xff09; 1&#xff09; 搭建namenode的高可用 Java 代码操作 HA 的 hdfs 代…

dolphinscheduler服务RPC框架源码解析(五)RPC提供者服务调用真实方法实现

RPC服务提供者的设计实现 1.概述2.RPC提供者服务调用真实方法设计3.RPC服务提供者调用真实方法实现3.1.工程结构3.1.RPC提供者服务调用真实方法入口类JdkDynamicServerHandler3.2. ServerMethodInvokerImpl类反射方法调用4.总结1.概述 上一篇文章我们已经看过了RPC提供者服务的…

MybatisPlus--mybatis升级版

一、快速入门 1.引入MybatisPlus的起步依赖 mybatisPlus官方提供了starter。其中集成了Mybatis和MybatisPlus的所有功能&#xff0c;对mybatis实现了润物无声&#xff0c;并且实现了自动装配效果。 因此使用了Mybatis的项目&#xff0c;也可以使用MybatisPlus的starter代替M…

我们来对接蓝凌OA --报文格式

题记 数智化办公专家、国家高新技术企业、知识管理国家标准制定者、信创供应商10强…等等&#xff0c;这些和咱们有关系吗&#xff01;&#xff01;不好意思&#xff0c;走错片场了&#xff0c;刚和项目经理在甲方那边吹牛B想想刚刚的大饼&#xff0c;看看支付宝余额&#xff…

Greenhills Lib操作-查看Lib信息与将lib中的data段link到指定区域

文章目录 前言Greenhillls中gsize的用法修改ld文件将lib中的data段指定区域示例定义与链接总结 前言 项目开发过程中&#xff0c;遇到客户开发ASW&#xff0c;提供Lib进行集成&#xff0c;但ASW中的标定量没有定义对应的data段&#xff0c;导致无法将标定量指定到特定的内存。…

数据结构之栈和队列算法题

一&#xff1a;有效括号数 学了栈之后这一题就比较简单了。 思路&#xff1a;1、左括号进栈 2、右括号出栈匹配。 完整代码&#xff1a; 因为使用C语言写的&#xff0c;所以里面包含了栈的实现 #include<stdio.h> #include<stdlib.h> #include<assert.h>…