akka 简单使用

news2024/10/6 8:39:41

由于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 {
    @Override
    public 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));
            // 传递给D
            actorRef.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 {
    @Override
    public 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
    @Override
    public 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
    @Override
    public 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>() {
            @Override
            public 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>() {
            @Override
            public void onSuccess(Object msg) throws Throwable {
                System.out.println("回复的消息:" + msg);
            }
        }, test.dispatcher());
        //失败,执行过程
        future.onFailure(new OnFailure() {
            @Override
            public 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 {

    //接收消息前置处理
    @Override
    public void preStart() {
        System.out.println("--------- 接收到消息  start");
    }

    //接收消息后置处理
    @Override
    public void postStop(){
        System.out.println("--------- 消息处理完毕  end");
    }

    // A接收消息
    @Override
    public 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");
        // 创建路由,路由到A
        ActorRef my_actor = actorSystem.actorOf(Props.create(MessageSendAndAccept.class), "my_actor");
        // 给 A 发消息
        my_actor.tell("哈哈哈a",ActorRef.noSender());
    }
}

并发 执行方法 例子

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

public class G extends AbstractActor {
    @Override
    public 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());
                //休眠 3s
                Thread.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.coloradmin.cn/o/800846.html

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

相关文章

3ds MAX绘制茶壶

综合一下之前的内容画个茶壶 长方形&#xff0c;然后转化为可编辑多边形&#xff0c;添加节点并设置圆角&#xff0c;如下图 车削生成一个圆环&#xff0c;其实这一步也可以用一个圆柱体和两个圆角圆柱体解决 效果如下&#xff1a; 茶壶的底座绘制好了 接下来是茶壶的上半边 …

牛客网面试必刷:CD12 换钱的最少货币数

牛客网面试必刷&#xff1a;CD12 换钱的最少货币数 前言一、动态规划&#xff08;1&#xff09;需要判断钱币和总金额&#xff08;2&#xff09;不需要判断钱币和总金额 前言 问题链接: CD12 换钱的最少货币数 一、动态规划 参考自&#xff1a;【编程题 动态规划】兑换零钱(…

Coremail敏感配置信息泄露

生活是美好的&#xff0c;生命在其间又是如此短促。既然活着&#xff0c;就应该好好地活。应该更珍惜自己生命的每个时刻&#xff0c;精神上的消沉无异于自杀。像往日一样正常的投入生活吧&#xff0c;即便是痛苦&#xff0c;也应该被看做是人的正常情感&#xff0c;甚至它是组…

【多线程】进程调度的基本过程

进程调度的基本过程 1. 什么是进程/任务&#xff08;Process/Task&#xff09;2. 描述一个进程3. 什么是进程调度&#xff1f;3.1 进程状态3.2 进程的优先级3.3 进程的上下文3.4 进程的记账信息 4. 组织这些进程 1. 什么是进程/任务&#xff08;Process/Task&#xff09; 操作…

【用户体验分析报告】 按需加载组件,导致组件渲染卡顿,影响交互体验?组件拆包预加载方案来了!

首先&#xff0c;我们看一些针对《如何提升应用首屏加载体验》的文章&#xff0c;提到的必不可少的措施&#xff0c;便是减少首屏幕加载资源的大小&#xff0c;而减少资源大小必然会想到按需加载措施。本文提到的便是一个基于webpack 插件与 react 组件实现的一套研发高度自定义…

nginx入门 - 学习笔记

一、初识 1、相关概念 1&#xff09;正向代理 一个位于客户端和原始服务器之间的服务器&#xff0c;为了从原始服务器取得内容&#xff0c;客户端向代理发送一个请求并指定目标&#xff0c;然后代理向原始服务器转交请求并将获得内容返回给客户端。 2&#xff09;反向代理…

【C++】多态,虚函数表相关问题解决

文章目录 多态概念及其触发条件重写和协变&#xff08;考点1&#xff09;&#xff08;考点2&#xff09; 虚函数表及其位置&#xff08;考点3&#xff09; 多继承中的虚函数表 多态概念及其触发条件 多态的概念&#xff1a;通俗来说&#xff0c;就是多种形态。具体点就是去完成…

DSA之图(2):图的存储结构

文章目录 0 图的结构1 邻接矩阵1.1 无向图的邻接矩阵1.2 有向图的邻接矩阵1.3 网&#xff08;有权图&#xff09;的邻接矩阵表示法1.4 邻接矩阵的建立1.4.1 采用邻接矩阵建立无向网1.4.2 采用邻接矩阵建立有向网 1.5 邻接矩阵的优缺点1.5.1 优点1.5.2 缺点 2 邻接表2.1 无向图的…

Java将汉字转拼音以及判断字符是否为汉字

首先是将汉字转换为拼音&#xff1a; 导入依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency>创建转拼音的静态方法toPinyin&#xf…

掌握 Python RegEx:深入探讨模式匹配

动动发财的小手&#xff0c;点个赞吧&#xff01; 什么是正则表达式&#xff1f; 正则表达式通常缩写为 regex&#xff0c;是处理文本的有效工具。本质上&#xff0c;它们由一系列建立搜索模式的字符组成。该模式可用于广泛的字符串操作&#xff0c;包括匹配模式、替换文本和分…

在线阅读版:《2023中国软件供应链安全分析报告》全文

聚焦源代码安全&#xff0c;网罗国内外最新资讯&#xff01; 专栏供应链安全 数字化时代&#xff0c;软件无处不在。软件如同社会中的“虚拟人”&#xff0c;已经成为支撑社会正常运转的最基本元素之一&#xff0c;软件的安全性问题也正在成为当今社会的根本性、基础性问题。 随…

火车头采集器伪原创【php源码】

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python中按钮的位置怎么摆放&#xff0c;python中按钮怎么设置颜色&#xff0c;现在让我们一起来看看吧&#xff01; 火车头采集ai伪原创插件截图&#xff1a; 1、用python的pygame,做一个按钮 唔...摁钮&#xff1f;…

【万字长文】SpringBoot整合SpringSecurity+JWT+Redis完整教程(提供Gitee源码)

前言&#xff1a;最近在学习SpringSecurity的过程中&#xff0c;参考了很多网上的教程&#xff0c;同时也参考了一些目前主流的开源框架&#xff0c;于是结合自己的思路写了一个SpringBoot整合SpringSecurityJWTRedis完整的项目&#xff0c;从0到1写完感觉还是收获到不少的&…

MYSQL导入excel数据后只显示500条

问题&#xff1a;明明显示数据全部导入成功&#xff0c;但是点开table后发现只显示了500条 解决步骤&#xff1a;&#xff08;以datagrip为例&#xff09; 其实大家已经把数据导入了&#xff0c;只是在工具里&#xff0c;它在设置里面做了限制&#xff0c;只显示500条数据。只…

Kotlin 内联函数语法之let、apply、also、run、with的用法与详解

一、介绍 kotlin的语法千奇百怪&#xff0c;今天我们将介绍项目中频率使用比较高的几个内联函数。 二、什么叫内联函数&#xff1f; 内联函数 的语义很简单&#xff1a;把函数体复制粘贴到函数调用处 。使用起来也毫无困难&#xff0c;用 inline关键字修饰函数即可。 语法&a…

三菱FX5U系列PLC内置定位功能的基本使用方法介绍

三菱FX5U系列PLC内置定位功能的基本使用方法介绍 三菱FX5U系列PLC本体自带的高速脉冲输出可以实现定位功能,具体的使用方法可参考以下内容: 参数设定 如下图所示,新建一个工程,在左侧的项目树中找到参数–模块参数—高速I/O,双击进入后找到输出功能—定位—点击进入详细设…

BHQ 1Mal,BHQ-1 Maleimide,BHQ1马来酰亚胺,黑洞猝灭剂

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ PART1----产品描述&#xff1a; BHQ-1 Maleimide黑洞猝灭剂-1(BHQ-1)被归类为暗猝灭剂&#xff0c;该淬灭剂能够将一定距离内荧光基团发出的光全部吸收&#xff0c;实现对荧光信号的淬灭&#xff0c;所以可得到更强的特异性…

基于SpringBoot+Vue的学习平台设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

神经网络的初始化方法

文章目录 1、随机初始化2、Xavier初始化3、He初始化4、权重预训练初始化5、零初始化 对于神经网络的训练过程中&#xff0c;合适的参数初始化方法有助于更好的处理梯度消失和梯度爆炸问题。通常有以下几种初始化方法&#xff1a; 1、随机初始化 随机初始化&#xff08;Random…

[JavaWeb]MySQL的安装与介绍

MySQL的安装与介绍 一.数据库相关概念1.1 数据库1.2 常见的关系型数据库管理系统 二.MySQL数据库1.MySQL的安装2.配置环境变量3.新建MySQL配置文件4.初始化MySQL5.注册MySQL的服务6.修改默认账户与密码7.连接MySQL服务8.MySQL的卸载 三.MySQL的数据模型1.关系型数据库 一.数据库…