前言
并发体系可以分为两层,上面一层是抽象的模型,下面一层是承载具体模型的技术机制。
- 模型可以分为: 共享内存模型、Actor模型、CSP模型等
- 承载模型的具体技术机制可以分为: 协程、多线程、多进程、集群分布式
常见的并发模型一般包括3类,基于线程与锁的内存共享模型
,actor模型
和CSP模型
。
Actor和CSP模型都属于高层次的抽象模型,底层的实现可能有多种。而线程与锁(也就是共享内存
)模型是较为底层的模型。
并发模型对比表
模型分类 | 优点 | 缺点 | 实现语言/库 |
---|---|---|---|
共享内存模型-锁模型 | • 贴近硬件架构,性能高 • 是其他并发模型的基础 | • 不支持分布式内存模型 • 调试测试困难 • 需避免事务副作用 | Java/C++等主流语言 |
共享内存模型-STM模型 | • 相比锁模型更简单 • 大部分情况下更高效 | • 不支持分布式内存模型 | Clojure语言标准库 |
消息传递模型-CSP模型 | • 相比锁模型更简单 • 容易实现高并发 | • 不支持分布式内存模型 | Go语言、Clojure的core.async库 |
消息传递模型-Actor模型 | • 容易实现高并发 • 支持分布式内存模型(跨节点同步) | • 存在信箱满后消息丢失问题 | Erlang、Java(Scala)的Akka库 |
事件循环(EventLoop)模型 | • 单线程资源占用小 • 容易实现高并发 | • 不支持分布式内存模型 | Java的Netty库(搭配多路复用IO) |
并发模型是指在计算中处理多个操作或任务的方式,它们通过不同的方法实现并发执行。以下是一些常见的并发模型:
常见的并发模型
1. 共享内存模型(锁模型):
描述:
- 在共享内存模型中,多个并发执行的任务可以通过对共享内存的读写来进行通信。
特点:
- 线程之间共享内存空间。
- 通过锁机制(如互斥锁、读写锁)来保证共享数据的一致性。
- 容易出现死锁和数据竞争问题。
应用:
- 常用于多线程编程,例如在操作系统中的线程同步和通信。
比如Java中的线程之间通信由JMM
控制
2. 消息传递模型:
描述:
- 在消息传递模型中,不同任务通过发送和接收消息进行通信,任务之间没有共享内存。
特点:
- 任务之间独立,通过消息传递实现通信。
- 可以提供更好的隔离性和并发性。
- 减少了共享状态可能带来的问题。
应用:
- 常用于分布式系统和消息队列等场景。
3. Actor 模型:
描述:
Actor
模型是一种并发计算模型,系统由独立的 Actor 组成,每个 Actor 都有自己的状态和行为。
特点:
- Actor 之间通过消息传递进行通信。
- Actor 是并发执行的基本单元,异步处理消息。
- 提供了良好的隔离性和并发性。
应用:
- 常用于构建高并发系统,如分布式系统和通信系统。
4. CSP(Communicating Sequential Processes)模型:
描述:
CSP
是一种基于通信过程
的并发模型,描述并发系统中独立组件之间的通信和协作。
特点:
- 进程通过通道进行消息通信。
- 通信是同步的,发送者和接收者需要达成一致。
- 支持并发执行和非确定性选择。
应用:
- 常用于描述并发系统的行为和设计并发算法。
5. STM(Software Transactional Memory)模型:
描述:
- STM 是一种并发编程模型,用于简化并发系统中的共享数据访问和管理事务。
特点:
- 提供原子性、隔离性和一致性的事务处理。
- 简化了并发编程,减少了手动管理锁的复杂性。
- 适用于函数式编程语言和需要高并发性的系统设计。
6. 事件循环和异步回调(EventLoop) 模型
这种模型通常用于I/O密集型应用,如网络服务器。在这种模型中,一个中央事件循环负责监听和分发事件,如I/O操作完成或消息到达。当事件发生时,相应的回调函数被调用来处理事件。
描述:
- EventLoop 模型是一种基于事件驱动的编程模型,通过事件循环(Event Loop)来处理异步事件和任务。
特点:
- 事件驱动:程序通过注册回调函数或事件处理器来响应事件,而不是通过阻塞调用等待事件发生。
- 非阻塞 I/O:通过异步 I/O 操作,在等待 I/O 完成时允许执行其他任务,提高系统的并发性能。
- 单线程:通常 EventLoop 模型是单线程的,通过事件循环依次处理事件,避免了多线程并发带来的复杂性。
- 事件队列:事件被放置在事件队列中,EventLoop 持续轮询事件队列并处理事件。
工作原理:
- 注册事件处理器:程序将事件处理器或回调函数注册到 EventLoop 中,用于处理特定事件。
- 事件循环:EventLoop 不断轮询事件队列,当有事件发生时,调用相应的事件处理器进行处理。
- 非阻塞处理:I/O 操作通常是非阻塞的,当 I/O 操作完成时,触发相应的回调函数处理结果。
- 事件驱动:整个程序的执行流程由事件的发生和处理来驱动,提高了系统的并发性和响应性。
优点:
- 高效的并发模型:适用于处理大量并发连接和事件的场景。
- 简化编程:通过事件驱动的方式处理任务,简化了异步编程的复杂性。
- 适用于 I/O 密集型任务:在处理大量 I/O 操作时具有良好的性能。
应用:
- Web 服务器和应用程序框架中常用于处理请求和响应。
- 客户端应用中处理用户交互和异步操作。
- 实时系统和网络通信中处理事件和消息。
7. 其他模型:
还有其他并发模型,如Futures、Promise、Fork/Join、生产者消费者模型和Master-Worker模型等。这些模型提供了不同的抽象和工具,以适应特定类型的并发问题。
总结
每种并发模型都有其特定的优缺点和适用场景,选择合适的模型可以帮助开发者更有效地构建高并发、可靠的应用程序。根据具体的应用需求和上下文,开发者可以选择最匹配的并发计算模型。