在本章中,咱们尝试创建一个通用术语,以便为Akka所针对的并发分布式系统进行通讯奠基坚实的基础。请注意,对于其中许多条款,没有单一的商定定义。咱们寻求提供将在Akka文档范围内使用的工做定义。html
并发与并行算法
并发和并行是相关的概念,但存在细微差异。并发意味着两个或多个任务正在取得进展,即便它们可能没有同时执行。这能够例如经过时间切片来实现,其中任务的各部分被顺序执行而且与其余任务的部分混合。另外一方面,并行性在执行能够真正同时发生时出现。服务器
异步与同步网络
若是调用方在方法返回值或抛出异常以前没法进行,则方法调用被视为同步。另外一方面,异步调用容许调用者在有限数量的步骤以后前进,而且能够经过一些附加机制(它能够是注册的回调,Future或消息)来发信号通知方法的完成。并发
同步API可使用阻塞来实现同步,但这不是必需的。CPU密集型任务可能会产生与阻塞相似的行为。一般,最好使用异步API,由于它们能够保证系统可以进步。Actor本质上是异步的:Actor能够在发送消息后继续进行,而无需等待实际的传递发生。dom
非阻塞与阻塞异步
咱们讨论阻塞,例如若是一个线程的延迟能够无限延迟其余一些线程。一个很好的例子是一个资源,它能够由一个使用互斥的线程专门使用。若是线程无限期地保留资源(例如意外地运行无限循环),则等待资源的其余线程没法进行。相反,非阻塞意味着没有线程可以无限期地延迟其余线程。分布式
非阻塞操做比阻塞操做更受欢迎,由于当系统包含阻塞操做时,系统的总体进度难以保证。ide
死锁与饥饿与现场锁定ui
当几个Actor彼此等待达到特定状态以便可以进展时,就会出现死锁。因为没有其余Actor达到某种状态,全部受影响的子系统都会中止运转。死锁与阻塞密切相关,由于参与者线程可以无限延迟其余线程的进展。
在死锁的状况下,没有参与者能够取得进展,而相反,当有参与者能够取得进展时会发生饥饿,但可能有一个或多个不可能。典型状况是天真调度算法的状况,该算法老是选择低优先级任务的高优先级任务。若是传入的高优先级任务的数量始终足够高,则不会完成任何低优先级任务。
Livelock相似于死锁,由于没有参与者取得进展。但不一样的是,参与者不是在等待其余人进步的状态下被冻结,而是不断改变他们的状态。两个参与者有两个相同资源可用的示例场景。他们每一个人都试图获取资源,但他们也检查对方是否也须要资源。若是资源是由其余参与者请求的,则他们尝试获取该资源的另外一个实例。在不幸的状况下,可能会发生这两个参与者在两种资源之间“反弹”,从未得到它,但老是屈服于另外一种资源。
竞争条件
当外部非肯定性效应可能违反关于一组事件的排序的假设时,咱们将其称为竞争条件。当多个线程具备共享可变状态时,一般会出现竞争条件,而且状态上的线程操做可能会交错,从而致使意外行为。虽然这是一种常见状况,但共享状态不必定具备竞争条件。一个示例能够是客户端将无序分组(例如UDP数据报)P1,P2发送到服务器。因为数据包可能经过不一样的网络路由传输,所以服务器可能先接收P2,而后接收P1。若是消息中不包含有关其发送顺序的信息,则服务器没法肯定它们是以不一样的顺序发送的。根据数据包的含义,这可能会致使竞争条件。
非阻塞保证(进展条件)
正如前面部分所讨论的那样,阻塞是不可取的,缘由有多种,包括死锁的危险和系统中的吞吐量下降。在如下部分中,咱们将讨论具备不一样强度的各类非阻塞特性。
Wait-freedom
wait-free方法表示若是保证每一个调用都以有限的步数完成。若是方法是无限制的,则步数具备有限的上限。
从这个定义能够看出,无等待方法永远不会阻塞,所以不会发生死锁。此外,因为每一个参与者能够在有限数量的步骤以后(当呼叫结束时)进展,所以无等待方法没有饥饿。
Lock-freedom
Lock-freedom是一种比wait-free更弱的。在无锁调用的状况下,无限次地某些方法在有限数量的步骤中完成。此定义意味着无锁调用不会出现死锁。另外一方面,某些呼叫在有限数量的步骤中完成的保证不足以保证全部呼叫最终完成。换句话说,Lock-freedom不足以保证缺少饥饿。
Obstruction-freedom
Obstruction-freedom是这里讨论的最弱的非阻碍保证。若是一个方法在一个时间点以后被隔离执行(其余线程没有任何步骤,例如:被暂停),则该方法被称为无障碍,它以有限的步数完成。全部无锁物体都是无障碍的,但相反的状况一般是不正确的。
乐观并发控制(OCC)方法一般是无障碍的。OCC方法是每一个参与者都尝试在共享对象上执行其操做,但若是参与者检测到其余参与者的冲突,则会回滚修改,并根据某些计划再次尝试。若是有一个时间点,其中一个参与者是惟一尝试的参与者,则操做将成功。
推荐文献:
下节再续!
原文:https://doc.akka.io/docs/akka/2.5/guide/tutorial_5.html