讨喜的隔离可变性-前言

简介:

曾有个的医嘱是这样说的:“如果它伤到了你,那就别再用它了”。在并发编程领域,共享可变性就是那个“它”。

虽然JDK的线程API使我们可以非常容易地创建线程,但如何防止线程冲突和逻辑混乱却又成了大问题。STM虽然可以解决部分问题,但是在一些类似Java这样的语言中,我们仍不得不非常小心谨慎地避免非托管可变变量和事务逻辑中产生某些副作用。而令人惊讶的是,当共享可变性消失的时候,所有那些令人纠结的问题也都随之消失了。

事实证明,在相同数据集上起多个线程互相冲突地执行是行不通的。幸运的是我们有更好的办法——基于事件的消息传递。通过这种方法,我们可以将任务当成是应用程序/JVM内部的轻量进程来对待。同时,我们将不可变消息传递给各个任务,从而避免每个任务都去抢占共享数据。一旦这些异步任务执行完毕,它们会将不可变的执行结果返回给另外的协调线程。在下面的章节中我们将学习如何设计这种带有“用于异步交换不可变消息的协调角色(actor)[1]”的应用程序。

虽然这种方法已经问世多年了,但在JVM领域却还是相对较新的技术。基于角色(actor)的模型在Erlang中是非常成功的(参见《Programming Erlang: Software for a Concurrent World》[Arm07]以及《Concnrrent Programming in Erlang》[VWWA96])。而当Scala 2003年被引入时,Erlang的基于角色(actor)的模型也同时被采纳并引入到JVM大家庭中(参见《Programming in Scala》[OSV08]以及《Programming Scala》[Sub09])。

在Java中,有大把基于角色(actor)的并发库[2]可供我们选择:ActorFoundary、Actorom、Actors Guild、Akka、FunctionalJava、Kilim、Jetlang等等。其中部分类库是以面向切面(AspectOriented)的字节码形式来进行组织的。同时,这些类库的成熟度和被大家的接受度也都不尽相同。

在本章中,我们将学习如何编写基于角色(actor)的并发程序。在大多数情况下,我们将使用Akka以便能够直奔核心概念。Akka是一个基于Scala的高性能解决方案,同时还提供了相当好用的Java API。我们既可以将其用于基于角色(actor)的并发,也可以将之用于STM(参见第6章)。

  1. 讨喜的隔离可变性-前言
  2. 讨喜的隔离可变性(一)用角色实现隔离可变性
  3. 讨喜的隔离可变性(二)角色的特性
  4. 讨喜的隔离可变性(三)创建角色
  5. 讨喜的隔离可变性(四)收发消息
  6. 讨喜的隔离可变性(五)同时使用多个角色
  7. 讨喜的隔离可变性(六)多角色协作
  8. 讨喜的隔离可变性(七)使用类型化角色
  9. 讨喜的隔离可变性(八)类型化角色和Murmurs
  10. 讨喜的隔离可变性(十)使用Transactor
  11. 讨喜的隔离可变性(十一)调和类型化角色
  12. 讨喜的隔离可变性(十二)基于角色模型的局限性和小结
  13. 讨喜的隔离可变性(十三)角色的特性

[1] 有人曾经问我这些角色(actor)与用例中其他角色(actor)如何交互的问题——答案是什么交互也不做。这些角色(actor)只对它们收到的消息起作用,即收到消息之后执行一些专门的任务,然后将响应消息传递给其他角色(actor)…如此周而复始地顺序执行。

[2] 试想一下如果我们只能选择其中一种方案的话,那将会是多么令人头痛的问题。

目录
相关文章
|
6月前
|
存储 Web App开发 运维
发布、部署,傻傻分不清楚?从概念到实际场景,再到工具应用,一篇文章让你彻底搞清楚
部署和发布是软件工程中经常互换使用的两个术语,甚至感觉是等价的。然而,它们是不同的! • 部署是将软件从一个受控环境转移到另一个受控环境,它的目的是将软件从开发状态转化为生产状态,使得软件可以为用户提供服务。 • 发布是将软件推向用户的过程,应用程序需要多次更新、安全补丁和代码更改,跨平台和环境部署需要对版本进行适当的管理,有一定的计划性和管控因素。
1523 1
|
数据采集 存储 Dubbo
亿级流量架构怎么做资源隔离?写得太好了!
常见的资源,例如磁盘、网络、CPU等等,都会存在竞争的问题,在构建分布式架构时,可以将原本连接在一起的组件、模块、资源拆分开来,以便达到最大的利用效率或性能。资源隔离之后,当某一部分组件出现故障时,可以隔离故障,方便定位的同时,阻止传播,避免出现滚雪球以及雪崩效应。
亿级流量架构怎么做资源隔离?写得太好了!
|
缓存 安全 Java
华为内部技术分享并发编程的不变性(Immutability)模式?
多个线程同时读写同一共享变量存在并发问题,这里的必要条件之一是读写,如果只有读,而没有写,不会有并发问题。
116 0
|
数据采集 缓存 NoSQL
go语言项目优化(经验之谈)
我的课题主要分为以下三章,斗鱼在GO的应用场景,GO在业务中如何优化,我们在GO中踩过了哪些坑。
go语言项目优化(经验之谈)
|
程序员
开发人员、程序员与计算机科学家三者之间的区别
导读:原文作者Alan Skorkin写了一篇《The Difference Between A Developer, A Programmer And A Computer Scientist》,文中讲述如何区分程序员、开发人员和计算机科学家之间的区别,发表了个人见解。
1155 0
|
存储 消息中间件 缓存
[原创]分布式系统之缓存的微观应用经验谈(一) 【设计基础细节篇】
近几个月一直在忙些琐事,几乎年后都没怎么闲过。忙忙碌碌中就进入了2018年的秋天了,不得不感叹时间总是如白驹过隙,也不知道收获了什么和失去了什么。最近稍微休息,买了两本与技术无关的书,其一是Yann Martel 写的《The High Mountains of Portugal》(葡萄牙的高山),发现阅读此书是需要一些耐心的,对人生暗喻很深,也有足够的留白,有兴趣的朋友可以细品下。
1389 0
|
监控 Java 开发者
讨喜的隔离可变性(十二)基于角色模型的局限性和小结
声明:本文是《Java虚拟机并发编程》的第五章,感谢华章出版社授权并发编程网站发布此文,禁止以任何形式转载此文。 截至目前我们所写的关于角色的例子中,所有角色及其客户端都运行于同一JVM进程中。但在现实生活中,有一部分开发者认为角色也应该像在Erlang中那样被用于进程间通信。
1459 0
|
Java Scala
讨喜的隔离可变性(十)使用Transactor
声明:本文是《Java虚拟机并发编程》的第五章,感谢华章出版社授权并发编程网站发布此文,禁止以任何形式转载此文。 Akka transactor或事务角色为我们提供了一种将多个角色的执行过程合并到一个事务中的方法。
1672 0