第五部分-并发编程模型1:Actor模型
1.前情提要
面向对象编程理论中,对象之间通信,依赖的是消息,但java里,对象之间通信,用的是对象方法
2.Actor模型
计算模型,计算单位Actor,所有的计算都在Actor中执行
Actor中一切都是actor,actor之间完全隔离,不共享任何变量
不共享变量,就不会有并发问题
java本身不支持actor模型,需要引入第三方类库Akka
3.代码范例
//该Actor当收到消息message后,
//会打印Hello message
static class HelloActor
extends UntypedActor {
@Override
public void onReceive(Object message) {
System.out.println("Hello " + message);
}
}
public static void main(String[] args) {
//创建Actor系统
ActorSystem system = ActorSystem.create("HelloSystem");
//创建HelloActor
ActorRef helloActor =
system.actorOf(Props.create(HelloActor.class));
//发送消息给HelloActor
helloActor.tell("Actor", ActorRef.noSender());
}
actor之间通信完美遵循了消息机制。而不是通过调用对象的方式
4.消息和对象方法的区别
actor内部有一个邮箱mailbox,接受到的消息先放到邮箱,如果有积压,新消息不会马上得到处理。actor是单线程处理消息。所以不会有并发问题
说白了,就是消费者线程的生产者-消费者模式
5.区别
对相关的方法调用,一般是同步的,而actor的消息机制是异步的。
6.Actor规范定义
1.处理能力,处理接收到的消息
2.存储能力,actor可以存储自己的内部状态
3.通信能力,actor可以和其他actor之间通信
7.actor实现线程安全的累加器
无锁算法,因为只有1个线程在消费,不会存在并发问题
//累加器
static class CounterActor extends UntypedActor {
private int counter = 0;
@Override
public void onReceive(Object message){
//如果接收到的消息是数字类型,执行累加操作,
//否则打印counter的值
if (message instanceof Number) {
counter += ((Number) message).intValue();
} else {
System.out.println(counter);
}
}
}
public static void main(String[] args) throws InterruptedException {
//创建Actor系统
ActorSystem system = ActorSystem.create("HelloSystem");
//4个线程生产消息
ExecutorService es = Executors.newFixedThreadPool(4);
//创建CounterActor
ActorRef counterActor =
system.actorOf(Props.create(CounterActor.class));
//生产4*100000个消息
for (int i=0; i<4; i++) {
es.execute(()->{
for (int j=0; j<100000; j++) {
counterActor.tell(1, ActorRef.noSender());
}
});
}
//关闭线程池
es.shutdown();
//等待CounterActor处理完所有消息
Thread.sleep(1000);
//打印结果
counterActor.tell("", ActorRef.noSender());
//关闭Actor系统
system.shutdown();
}
8.总结
actor计算模型,基本计算单元。消息通信。
9.应用
spark,filink,play
原创:做时间的朋友