akka 简单使用

由于AKka的核心是Actor,而Actor是按照Actor模型进行实现的,所以在使用Akka之前,有必要弄清楚什么是Actor模型。

Actor模型最早是1973年Carl Hewitt、Peter Bishop和Richard Seiger的论文中出现的,受物理学中的广义相对论(general relativity)和量子力学(quantum mechanics)所启发,为解决并发计算的一个数学模型。

Actor模型所推崇的哲学是”一切皆是Actor“,这与面向对象编程的”一切皆是对象“类似。但不同的是,在模型中,Actor是一个运算实体,它遵循以下规则: 接受外部消息,不占用调用方(消息发送者)的CPU时间片 通过消息改变自身的状态 创建有限数量的新Actor 发送有限数量的消息给其他Actor 很多语言都实现了Actor模型,而其中最出名的实现要属Erlang的。Akka的实现借鉴了不少Erlang的经验。

<dependency><groupId>com.typesafe.akka</groupId><artifactId>akka-actor_2.11</artifactId><version>2.4.7</version>
</dependency>

tell 发送一个消息到目标Actor后立刻返回

public class C extends AbstractActor {@Overridepublic Receive createReceive() {return receiveBuilder().match(Object.class,obj->{if(obj instanceof String){System.out.println("C:  D你回复给我的消息我收到了!");return;}SomeOne someOne = (SomeOne) obj;System.out.println("C:  C接收到消息:"+someOne.toString());// 创建D路由ActorRef actorRef = this.getContext().actorOf(Props.create(D.class, D::new));// 传递给DactorRef.tell(someOne,self());// 路由给D(和tell 实现的功能一样)//actorRef.forward(someOne,getContext());}).build();}public static void main(String[] args) {ActorSystem ok = ActorSystem.create("ok");ActorRef actorRef = ok.actorOf(Props.create(C.class, C::new));Scanner sc = new Scanner(System.in);System.out.print("请输入:");String s = sc.nextLine();actorRef.tell(new SomeOne(1,s,0),ActorRef.noSender());}
}public class D extends AbstractActor {@Overridepublic Receive createReceive() {return receiveBuilder().match(Object.class,obj->{SomeOne someOne = (SomeOne) obj;System.out.println("D:  D接收到C 传过来的消息:"+someOne.toString());Thread.sleep(2000);sender().tell("D:  我再把消息发给你C",self());}).build();}
}
注意:
ActorSystem是一个较重的存在,一般一个应用里,只需要一个ActorSystem。
在同一个ActorySystem中,Actor不能重名。

ask 发送一个消息到目标Actor,并返回一个Future对象,可以通过该对象获取结果。但前提是目标Actor会有Reply才行,如果没有Reply,则抛出超时异常

public class A extends AbstractActor {// 接收到对象SomeOne@Overridepublic Receive createReceive() {return receiveBuilder().match(Object.class,obj ->{if(obj instanceof SomeOne){SomeOne someOne = (SomeOne) obj;System.out.println(" A 收到 SomeOne 对象:"+someOne.toString());someOne.setAge(someOne.getAge()+1);// 业务。。。Thread.sleep(1000);// 返回结果this.getSender().tell("xxx",getSelf());}}).build();}## Await 同步阻塞等待结果public static void main(String[] args) {//ActorSystem test = ActorSystem.create("test");ActorRef actorRefA = test.actorOf(Props.create(A.class, A::new));SomeOne someOne = new SomeOne(1,"哈哈哈ok",10);// 2 分钟超时Timeout timeout = new Timeout(Duration.create(2, TimeUnit.SECONDS));Future<Object> future = Patterns.ask(actorRefA, someOne, timeout); //ref,消息体,超时时间try {// Await 同步阻塞等待方式String reply = (String) Await.result(future, timeout.duration());System.out.println("回复的消息: " + reply);} catch (Exception e) {e.printStackTrace();}}
public class A extends AbstractActor {// 接收到对象SomeOne@Overridepublic Receive createReceive() {return receiveBuilder().match(Object.class,obj ->{if(obj instanceof SomeOne){SomeOne someOne = (SomeOne) obj;System.out.println(" A 收到 SomeOne 对象:"+someOne.toString());someOne.setAge(someOne.getAge()+1);// 业务。。。Thread.sleep(1000);// 返回结果this.getSender().tell("xxx",getSelf());}}).build();}## future 异步等待结果。
public static void main(String[] args) {//ActorSystem test = ActorSystem.create("test");ActorRef actorRefA = test.actorOf(Props.create(A.class, A::new));SomeOne someOne = new SomeOne(1,"哈哈哈ok",10);// 2 分钟超时Timeout timeout = new Timeout(Duration.create(2, TimeUnit.SECONDS));//ref,消息体,超时时间Future<Object> future = Patterns.ask(actorRefA, someOne, timeout);// 异步方式future.onComplete(new OnComplete<Object>() {@Overridepublic void onComplete(Throwable throwable, Object o) throws Throwable {if (throwable != null) {System.out.println("返回结果异常:" + throwable.getMessage());} else {System.out.println("返回消息:" + o);}}}, test.dispatcher());// 成功,执行过程future.onSuccess(new OnSuccess<Object>() {@Overridepublic void onSuccess(Object msg) throws Throwable {System.out.println("回复的消息:" + msg);}}, test.dispatcher());//失败,执行过程future.onFailure(new OnFailure() {@Overridepublic void onFailure(Throwable throwable) throws Throwable {if (throwable instanceof TimeoutException) {System.out.println("服务超时");} else {System.out.println("未知错误");}}}, test.dispatcher());}

tell 前置后置处理,销毁线程 的例子

public class MessageSendAndAccept extends AbstractActor {//接收消息前置处理@Overridepublic void preStart() {System.out.println("--------- 接收到消息  start");}//接收消息后置处理@Overridepublic void postStop(){System.out.println("--------- 消息处理完毕  end");}// A接收消息@Overridepublic Receive createReceive() {return receiveBuilder().match(String.class,result ->{consoleLog(result);}).build();}//打印public void consoleLog(String log){System.out.println("接收到内容:"+log);//销毁线程getContext().stop(self());}public static void main(String[] args) {// 创建ActorSystem仓库ActorSystem actorSystem = ActorSystem.create("demo");// 创建路由,路由到AActorRef my_actor = actorSystem.actorOf(Props.create(MessageSendAndAccept.class), "my_actor");// 给 A 发消息my_actor.tell("哈哈哈a",ActorRef.noSender());}
}

并发 执行方法 例子

创建多个actor 同时执行就好了

public class G extends AbstractActor {@Overridepublic Receive createReceive() {return receiveBuilder().match(Object.class,obj->{if(obj instanceof String){System.out.println(obj + ",time="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"--- Thread ---"+Thread.currentThread().getName());//休眠 3sThread.sleep(3000L);System.out.println(Thread.currentThread().getName()+"---END");return;}}).build();}public static void main(String[] args) {ActorSystem ok = ActorSystem.create("ok");ActorRef actorRef_0 = ok.actorOf(Props.create(G.class, G::new));actorRef_0.tell("a",ActorRef.noSender());ActorRef actorRef_1 = ok.actorOf(Props.create(G.class, G::new));actorRef_1.tell("b",ActorRef.noSender());ActorRef actorRef_2 = ok.actorOf(Props.create(G.class, G::new));actorRef_2.tell("c",ActorRef.noSender());}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/10454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器数据恢复-误操作导致存储VDisk丢失的数据恢复案例

服务器数据恢复环境&#xff1a; IBM某型号存储&#xff1b; Solaris操作系统&#xff0c;部署Oracle数据库。 服务器故障&#xff1a; 重建MDisk导致对应的存储池中的VDisk丢失&#xff0c;导致Solaris操作系统中的Oracle数据库无法使用。 服务器数据恢复过程&#xff1a; 1、…

理解Android中不同的Context

作者&#xff1a;两日的blog Context是什么&#xff0c;有什么用 在Android开发中&#xff0c;Context是一个抽象类&#xff0c;它是Android应用程序环境的一部分。它提供了访问应用程序资源和执行各种操作的接口。可以说&#xff0c;Context是Android应用程序与系统环境进行交…

面向对象——步入JavaScript高级阶段的敲门砖

目录 前言一、认识对象1.什么是对象2.对象的方法3.对象的遍历4.对象的深浅克隆 二、认识函数上下文1.函数的上下文规则 ★2.call和apply ★ 三、构造函数1.用new操作符调用函数2.类与实例3.构造函数和类" 四、原型和原型链1.prototype和原型链查找 ★2.在prototype上添加方…

Windows下安装Hadoop(手把手包成功安装)

Windows下安装Hadoop&#xff08;手把手包成功安装&#xff09; Windows下安装Hadoop&#xff08;手把手包成功安装&#xff09;一、环境准备1.1、查看是否安装了java环境 二、下载Hadoop的相关文件三、解压Hadoop安装包四、替换bin文件夹五、配置Hadoop环境变量六、检查环境变…

【数学建模】时间序列分析

文章目录 1. 条件2. 模型分类3. SPSS处理时间序列 1. 条件 1.使用于具有时间、数值两种要素 2.数据具有周期性可以使用时间序列分解 2. 模型分类 叠加模型【YTSCI】 序列的季节波动变化越来越大&#xff0c;反映变动之间的关系发生变化乘积序列【YTSC*I】 时间序列波动保持恒…

【多模态】16、DetCLIP | 构建超大词汇字典来进行开放世界目标检测

论文&#xff1a;DetCLIP: Dictionary-Enriched Visual-Concept Paralleled Pre-training for Open-world Detection 代码&#xff1a;无。。。 出处&#xff1a;NIPS2022 | 华为诺亚方舟 | 中山大学 | 香港科技大学 效果&#xff1a; 在 LVIS 的 1203 个类别上超越了 GLIP…

【树上乘法原理】ICPC Shanghai 2021 G, Edge Groups

http://oj.daimayuan.top/course/8/problem/400 题意&#xff1a; 思路&#xff1a; 求方案数&#xff0c;考虑组合数学 手摸一下样例发现&#xff0c;对于一棵子树&#xff0c;若边数为偶数&#xff0c;那么可以内部匹配&#xff0c;但是如果边数为奇数&#xff0c;那么就一…

嵌入式:QT Day2

一、继续完善登录框&#xff0c;当登陆成功时&#xff0c;关闭登陆页面&#xff0c;跳转到新的界面中 源码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> //用于打印输出 #include <QIcon> …

无涯教程-jQuery - jQuery.getScript( url, callback )方法函数

jQuery.getScript(url&#xff0c;[callback])方法使用HTTP GET请求加载并执行JavaScript文件。 该方法返回XMLHttpRequest对象。 jQuery.getScript( url, [callback] ) - 语法 $.getScript( url, [callback] ) 这是此方法使用的所有参数的描述- url - 包含请求…

mac 移动硬盘未正常退出,再次链接无法读取(显示)

&#xff08;1&#xff09;首先插入自己的硬盘&#xff0c;然后找到mac的磁盘工具 &#xff08;2&#xff09;打开磁盘工具&#xff0c;发现自己的磁盘分区在卸载状态&#xff1b;点击无法成功装载。 &#xff08;3&#xff09;打开终端&#xff0c;输入 diskutil list查看自…

Redis应用(1)——生成全局唯一标识ID

1 概述 在实际项目中&#xff0c;根据不同的业务逻辑需要生成唯一的标识id &#xff0c;如购买商品生成的订单号。尽管这个标识id功能非常的简单&#xff0c;但是如果不能成功的生成唯一标识id&#xff0c;那将会影响后续的业务逻辑 。我们可以使用数据库去生成唯一标识id&…

经营在线业务的首选客服工具--SS客服

随着网购正在快速取代传统零售业&#xff0c;各行各业的企业都在大力发展电子商务以取悦客户。但是&#xff0c;有这么多可用的电子商务平台&#xff0c;选择一款符合自己发展的平台确实不容易。电子商务平台不仅是企业在线销售产品和服务的地方&#xff0c;也是他们管理日常运…

Qt Core学习日记——第七天QMetaObject(上)

每一个声明Q_OBJECT的类都具有QMetaObject对象 Q_OBJECT宏源代码&#xff1a; #define Q_OBJECT \ public: \ QT_WARNING_PUSH \ Q_OBJECT_NO_OVERRIDE_WARNING \ static const QMetaObject staticMetaObject; \ virtual const QMetaObject *metaObject() const; \ vir…

深度学习入门教程(2):使用预训练模型来文字生成图片TextToImageGenerationWithNetwork

本深度学习入门教程是在polyu HPCStudio 启发以及资源支持下进行的&#xff0c;在此也感谢polyu以及提供支持的老师。 本文内容&#xff1a;在GoogleColab平台上使用预训练模型来文字生成图片Text To Image Generation With Network &#xff08;1&#xff09;你会学到什么&a…

Fiddler使用教程|渗透测试工具使用方法Fiddler

提示&#xff1a;如有问题可联系我&#xff0c;24小时在线 文章目录 前言一、Fiddler界面介绍二、菜单栏1.菜单Fiddler工具栏介绍Fiddler命令行工具详解 前言 网络渗透测试工具&#xff1a; Fiddler是目前最常用的http抓包工具之一。 Fiddler是功能非常强大&#xff0c;是web…

伦敦金在非农双向挂单

对伦敦金投资有一定经验的投资者都知道&#xff0c;在非农时期&#xff0c;伦敦金市场会出现很大的波动&#xff0c;那么我们如何才能抓住这些波动呢&#xff1f;答案是很难的。但是&#xff0c;有些投资者在多年实践中发明了一种双向挂单的方法&#xff0c;这里和大家一切分享…

向量数据库Milvus的四个版本

目录 MilvusLite版 单机版 分布式版 Milvus Cloud版 Milvus是一个功能强大的向量数据库管理系统,提供了多种版本,以满足不同用户的需求。以下是关于Milvus四个版本的具体介绍。 MilvusLite版 MilvusLite版是Milvus的轻量级版本,适合于小规模数据集和高性能计算场景。…

el-popover在原生table中,弹出多个以及内部取消按钮无效问题

问题&#xff1a;当el-popover和原生table同时使用的时候会失效&#xff08;不是el-table) <el-popover placement"bottom" width"500" trigger"click" :key"popover-${item.id}"></el-popover> 解决&#xff1a; :key…

vue 项目中使用阿里巴巴矢量图标库

1.网址&#xff1a;https://www.iconfont.cn/ 2.手动创建自己的项目图标库 选中图标 → 添加入库&#xff08;点击购物车&#xff09;→ 完成后点击上方菜单栏的购物车 → 添加至项目&#xff08;没有则新建项目&#xff09;→ 自动打开项目图标库 → 点击下载至本地 → 点击de…

【Redis-02】Redis的缓存

Redis的缓存 1.概念1.1什么是缓存1.2为什么使用缓存1.3如何使用1.3.1不适用缓存之前1.3.2 缓存模型和思路&#xff08;使用方法&#xff09;1.3.3 使用之后 2.缓存更新策略2.1数据库缓存不一致解决方案2.2数据库和缓存不一致采用什么方案2.3代码实例 3.缓存穿透3.1缓存穿透是什…