极客时间:Java并发编程实战
1 Actor模型:面向对象原生的并发模型
- 概念
Actor模型本质上是一种计算模型,基本的计算单元称为Actor,Actor之间通过消息进行通信;
在Actor模型中,所有的计算都是在Actor中执行的。
在面向对象编程里面,一切都是对象;
在Actor模型里,一切都是Actor,并且Actor之间是完全隔离的,不会共享任何变量。
在Java领域,除了可以使用Akka来支持Actor模型外,还可以使用Vert.x,不过相对来说Vert.x更像是Actor模型的隐式实现,对应关系不像Akka那样明显,不过本质上也是一种Actor模型。
Actor可以创建新的Actor,这些Actor最终会呈现出一个树状结构,非常像现实世界里的组织结构,所以利用Actor模型来对程序进行建模,和现实世界的匹配度非常高。
Actor模型和现实世界一样都是异步模型,理论上不保证消息百分百送达,也不保证消息送达的顺序和发送的顺序是一致的,甚至无法保证消息会被百分百处理。
虽然实现Actor模型的厂商都在试图解决这些问题,但遗憾的是解决得并不完美,所以使用Actor模型也是有成本的。
- 消息和对象方法的区别
Actor内部有一个邮箱(Mailbox)
接收到的消息都是先放到邮箱里,如果邮箱里有积压的消息,那么新收到的消息就不会马上得到处理
也正是因为Actor使用单线程处理消息,所以不会出现并发问题
你可以把Actor内部的工作模式想象成只有一个消费者线程的生产者-消费者模式
所以,在Actor模型里,发送消息仅仅是把消息发出去而已,接收消息的Actor在接收到消息后,也不一定会立即处理
也就是说Actor中的消息机制完全是异步的。而调用对象方法,实际上是同步的,对象方法return之前,调用方会一直等待
除此之外,调用对象方法,需要持有对象的引用,所有的对象必须在同一个进程中
而在Actor中发送消息,类似于现实中的写信,只需要知道对方的地址就可以,发送消息和接收消息的Actor可以不在一个进程中,也可以不在同一台机器上。因此,Actor模型不但适用于并发计算,还适用于分布式计算。
- 案例:实现累加器
2 软件事务内存:借鉴数据库的并发经验
使用MVCC实现的STM来实现线程安全
手写STM:操作的对象类、当前事务类、操作当前事务的类、实现方法类
VersionedRef
作用:将对象value包装成带版本 的对象;
按照MVCC理论,数据的每一次修改都对应着一个唯一的版本 ,所以不存在仅仅改变value或者version的情况,用不变性模式就可以很好地解决这个问题,所以VersionedRef这个类被我们设计成了不可变的
TxnRef:
作用:负责完成事务内的读写操作(所有对数据的读写操作,一定是在一个事务里面)
读写操作委托给了接口Txn
Txn:
TxnRef的读写操作委托给了接口Txn,Txn代表的是读写操作所在的当前事务, 内部持有的curRef代表的
是系统中的最新值
STMTxn:
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!