并发编程之同步/异步/回调/任务 工作流程分析图解
创作时间:
作者:
@小白创作中心
并发编程之同步/异步/回调/任务 工作流程分析图解
引用
CSDN
1.
https://blog.csdn.net/alises1314/article/details/143496871
在现代软件开发中,多线程和异步编程已成为提升应用性能和响应速度的关键技术。Java提供了强大的并发工具,如Thread、Runnable、Callable和Future,这些工具使开发者能够有效地管理线程和任务。
1. 同步与异步
1.1 同步与异步设计图
同步处理:
阻塞当前线程:在等待操作完成时,当前线程不能执行其他任务。
顺序执行:任务按照顺序一个接一个地执行。
等待结果:线程等待操作完成并获取结果。
异步处理:
不阻塞当前线程:在等待操作完成时,当前线程可以继续执行其他任务。
并行执行:多个任务可以同时执行,提高效率。
回调结果:操作完成后,通过回调函数或其他机制返回结果。
1.2 同步处理时序图
- 客户端请求数据:客户端发起一个请求,要求同步API提供数据。
- 同步API查询数据库:同步API将请求转发到数据库。
- 数据库返回结果:数据库处理请求并将结果返回给同步API。
- 同步API返回结果:同步API将数据库的结果返回给客户端。
1.3 异步处理时序图
- 客户端发起异步请求:客户端向异步API发起一个请求,要求查询数据,但不会等待响应。
- 异步API查询数据库:异步API将查询任务发送到数据库,并立即返回,不会阻塞。
- 数据库处理完毕:数据库在后台处理查询任务。
- 调用回调函数:一旦数据库处理完毕,异步API调用预先定义的回调函数。
- 返回结果给客户端:回调函数将结果返回给客户端。
1.4 回调时序图
- 客户端注册回调并发起异步请求:客户端向异步API发起请求,并提供一个回调函数,用于在异步操作完成后接收结果。
- 异步API立即返回:异步API接收请求后立即返回,不等待异步操作完成。
- 客户端继续执行:客户端可以继续执行其他任务,而不必等待异步操作的结果。
- 异步API执行异步操作:异步API在后台执行异步操作。
- 异步操作完成:一旦异步操作完成,异步API调用之前注册的回调函数。
- 回调执行:回调函数被执行,处理异步操作的结果。
- 返回结果给客户端:回调函数将异步操作的结果返回给客户端。
2. 任务执行单元
2.1 Thread 工作模式
- 创建 Thread 对象:通过
new Thread()
或其子类构造函数创建一个新的线程对象。 - 设置 Runnable 任务:为线程对象设置一个实现了
Runnable
接口的任务。 - 启动线程:调用线程对象的
start()
方法来启动线程。 - 线程状态:线程可以处于以下几种状态之一:
- 运行中:线程正在执行其
run()
方法。 - 阻塞:线程等待监视器锁。
- 等待:线程等待某个条件或超时。
- 终止:线程执行完毕或被中断。
- 执行 run 方法:线程开始执行其
run()
方法。 - 调用 Runnable.run:
Thread
类的run()
方法内部调用Runnable
任务的run()
方法。 - 执行任务:实际的
Runnable
任务开始执行。 - 任务执行完毕:
Runnable
任务执行完毕。 - 线程结束:任务执行完毕后,线程结束其生命周期。
- 等待解锁:如果线程需要访问同步代码块或方法,它可能会因为等待锁而被阻塞。
- 等待条件:线程可能在
wait()
、join()
或其他等待条件下等待。
3. 任务单元
3.1 Runnable 无返回值
Runnable
接口是Java中一个功能性接口,用于那些可以被线程执行的任务。它只包含一个方法run()
,该方法不接受参数,也不返回任何值(即返回类型为void
)。
@FunctionalInterface
public interface Runnable {
void run();
}
使用Runnable
的步骤:
- 实现 Runnable 接口:创建一个类实现
Runnable
接口,并覆盖run()
方法来定义任务的执行逻辑。
public class MyRunnableTask implements Runnable {
@Override
public void run() {
// 任务执行的代码
System.out.println("任务正在执行");
}
}
- 创建 Thread 对象:创建
Thread
对象时,将实现了Runnable
接口的类的实例作为参数传递给Thread
构造函数。
public class Main {
public static void main(String[] args) {
MyRunnableTask task = new MyRunnableTask();
Thread thread = new Thread(task);
thread.start(); // 启动线程,执行任务
}
}
- 启动线程:调用
Thread
对象的start()
方法来启动线程。这将导致在新线程中异步执行run()
方法。
3.2 Callable 有返回值
Callable
接口是Java并发编程中的一部分,它允许任务返回结果和抛出异常。以下是Callable
接口的基本设计和用法的说明:
接口定义
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Callable<V>
:Callable
是一个泛型接口,V
代表返回值的类型。call()
:这是一个方法,它不接受任何参数,可以返回任何类型的值(V
),并且可以抛出任何类型的异常。
使用Callable
的步骤:
- 实现 Callable 接口:创建一个类实现
Callable
接口,并覆盖call()
方法来定义任务的执行逻辑和返回结果。
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
// 任务执行的代码
return "任务结果";
}
}
- 创建 FutureTask 对象:将实现了
Callable
接口的类的实例传递给FutureTask
构造函数。
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable task = new MyCallable();
FutureTask<String> futureTask = new FutureTask<>(task);
Thread thread = new Thread(futureTask);
thread.start(); // 启动线程,执行任务
// 获取任务结果
String result = futureTask.get();
System.out.println("任务结果: " + result);
}
}
- 启动线程:调用
Thread
对象的start()
方法来启动线程。这将导致在新线程中异步执行FutureTask
的run()
方法,该方法内部会调用Callable
的call()
方法。
4. 异步结果
4.1 Future
- 提交异步任务:通过
ExecutorService
提交一个异步任务。 - ExecutorService:执行异步任务的服务。
- Future对象:
ExecutorService
提交任务后返回一个Future
对象,该对象可以用来检查计算是否完成、等待计算完成、取消任务和获取计算结果。 - 检查完成:通过
Future
对象的isDone()
方法检查异步任务是否已完成。 - 已完成:如果任务已完成,通过
Future
对象的get()
方法获取结果。 - 获取结果:处理异步任务的结果。
- 未完成:如果任务未完成,可以选择等待或取消任务。
- 等待或取消:等待任务完成或取消任务。
- 等待超时:设置超时时间等待任务完成。
- 取消任务:尝试取消任务。
- 处理结果:处理异步任务的结果。
- 处理超时:处理等待超时的情况。
- 处理取消:处理任务取消的情况
- 客户端提交任务:客户端向执行器服务提交一个实现了
Callable
接口的异步任务。 - 执行器服务执行任务:执行器服务接收到任务后,开始执行异步任务。
- 异步任务设置结果:异步任务执行完毕后,将结果设置到与
Future
对象关联的内部存储中。 - 客户端获取结果:客户端调用
Future
对象的get()
方法来获取异步任务的结果。 - 任务已完成:如果异步任务已经完成,
Future
对象将返回结果给客户端。 - 任务未完成:如果异步任务还未完成,
Future
对象将导致客户端阻塞等待,直到任务完成并返回结果。
- Future:这是一个接口,定义了以下方法:
cancel(boolean mayInterruptIfRunning)
:尝试取消执行任务。isCancelled()
:检查任务是否已被取消。isDone()
:检查任务是否已完成。get()
:获取任务的结果,如果任务尚未完成,则阻塞等待。get(long timeout, TimeUnit unit)
:在指定的超时时间内获取任务的结果。
4.2 FutureTask
- 创建 FutureTask 对象:创建一个
FutureTask
对象,它封装了一个Callable
对象(如果任务有返回值)或Runnable
对象(如果任务没有返回值)。 - 提交任务:决定是通过
ExecutorService
提交任务还是直接在当前线程执行。 - 执行任务:如果通过
ExecutorService
提交,任务将被安排在线程池中的某个线程执行。如果是直接执行,则调用FutureTask
的run
方法。 - 任务状态:检查任务的执行状态。
- 完成:如果任务正常完成,则设置任务的结果。
- 被取消:如果任务在执行前被取消,则标记任务为取消状态。
- 异常:如果任务执行过程中抛出异常,则设置异常信息。
- 提供结果给调用者:一旦任务完成(无论是正常完成、被取消还是抛出异常),
FutureTask
将能够提供结果给调用get
方法的线程。
- FutureTask:这是一个类,它实现了
Runnable
和Future
接口。它包含任务的执行结果(result
)、任务完成状态(done
)和取消状态(cancelled
)。 - Callable:这是一个接口,它允许任务返回结果和抛出异常。
- Runnable:这是一个接口,它允许任务被线程执行,但不返回结果和异常。
- TimeUnit:这是一个枚举,它定义了时间单位,用于
get
方法的超时参数。
热门推荐
职场白领如何用成就点亮爱情?
爱情中的角色失衡?教你重拾自信!
鱼缸清道夫泛滥怎么办?多种实用处理方法详解
《自卑与超越》:低谷期的情感救赎
《解忧杂货店》:低谷期的心灵慰藉
张朝阳物理课揭秘:红旗混动技术究竟有多牛?
如何解决大门尺寸不合适的装修问题?还有哪些类似装修问题需要注意?
福彩3D开奖数据大揭秘:如何看懂连线走势图?
告别“相亲综合征”:从心态到技巧,教你找到Mr/Miss Right
婚恋中介服务平台如何保障你的相亲安全?
相亲防骗:如何识别虚假信号?
从人民公园到网络平台:中国相亲文化的变迁之旅
购买福彩3D前必看!这些规定你了解吗?
最新一期福彩3D开奖结果揭晓!
《克莱默夫妇》:一部关于夫妻关系修复的经典启示录
2025年油车置换条件全解析:补贴标准、申请流程与注意事项
用爱修复:七个心理小技巧让婚姻重获新生
一封改变命运的信:如何用走心文案修复夫妻关系
微信小程序管理技巧大揭秘!
双十一期间如何快速清理微信小程序提升手机性能?
冬季自驾游云南:淮南出发,穿越多省,尽享云南温暖之旅
枣树主要虫害及防治技术
常见果树蛀果害虫的防治方法
嗨森课堂:旅行摄影,捕捉瞬间与故事的艺术
婚检前要注意什么
京港地铁4号线-大兴线:最新运营调整与特色服务全解析
低价股行情如火如荼 后市如何演绎?
京港地铁4号线换乘新指南上线!7大站点增设临线信息标识
日语中"该死"的多种表达方式
北风起,晒陈皮,教你8大晒皮重点!