首页 文章 精选 留言 我的

精选列表

搜索[向量化],共10003篇文章
优秀的个人博客,低调大师

阿联酋向所有公民和居民免费提供 ChatGPT Plus

外媒报道称,阿拉伯联合酋长国(UAE)将成为全球首个为全体公民(citizens)和居民(residents)免费提供 ChatGPT Plus 服务的国家。 5 月 22 日,G42、OpenAI、甲骨文、英伟达、软银和思科宣布共同打造“星际之门阿联酋”(Stargate UAE),这是 OpenAI 人工智能基础设施平台 Stargate 的首个国际部署项目。 而作为“星际之门阿联酋”项目的一项福利措施,阿联酋所有公民和居民都可以免费获得 ChatGPT Plus 服务,该服务目前的月费为 20 美元。

优秀的个人博客,低调大师

向 Graalvm Native 友好靠近

本次更新最重要的是增加了Solon APT项目,为更简单的完成 Graalvm Native 打包提供了帮助;其次是增加了 @ProxyComponent 和 @SolonMain 注解;以及优化了Solon Bean 的生命周期。 简介: Solon 是一个高效的应用开发框架:更快、更小、更简单。生态情况包括: 150 来个能力扩展插件 支持 Java、Kotlin、Groovy 三种语言开箱即用的特性 官网 、 交流群,以及技术支持 Solon Initializr 用户落地的开源或商业项目 Solon 的生产力价值: 更快、更小。带来IT成本、运维成本下降 更简单。节省人力成本 Solon 的国产性: Solon 在通讯框架、基础框架、能力框架,等方面提供了完整"国产"的方案支持。(Java 不是国产?这个没法了) 150来个生态插件,覆盖各种不同的应用开发场景: 相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 ~ 10 倍。(更快) qps 高 2~ 3 倍。(更高) 运行时内存节省 1/3 ~ 1/2。(更少) 打包可以缩小到 1/2 ~ 1/10;比如,300Mb 的变成了 23Mb。(更小) 同时支持 jdk8, jdk11, jdk17, jdk19。 似曾相似的体验,入门更简单,迁移很方便: @Controller public class App { public static void main(String[] args) { Solon.start(App.class, args, app->{ //手写模式 app.get("/", ctx -> ctx.outputAsJson("{message:'Hello world!'}")) }); } //注解模式 @Get @Socket @Mapping("/hello") public String hello(String name) { return String.format("Hello %s!", name); } } 入门探索视频(用户录制): 本次更新: 新增 solon.proxy 插件 新增 solon.proxy.apt 插件 新增 solon.graalvm 插件 新增 solon.graalvm.apt 插件 新增 solon.view 插件,为所有视频插件提供公共的配置和工具帮助 调整 mybatis-solon-plugin 插件,取消 mappers 检测异常,改为警告日志 调整 captcha-solon-plugin 插件,延迟内部 Bean 的构建时机 调整 BeanInvocationHandler 内部代码,简化并增加 AptProxy 调用 调整 dateAsFormat 配置增加对 LocalDate 和 LocalDateTime 的支持 调整 Plugin::Init 标为弃用, 并由 InitializingBean 接口接替 调整 Plugin 接口不再做为组件形态,有生命周期需求的可改为 LifecycleBean 接口 调整 Plugin Spi 实例化改为 Bean 模式,之前为不能注入的 New 模式 调整 AopContext 标注 beanOnloaded 为弃用。事件概念调整为容器内部的生命周期概念 调整 AopContext 增加 start(),stop(),lifecycle() 接口;强化生命周期管理概念 调整 Lifecycle 增加可异常选择,并标注 @FunctionalInterface 调整 调整打包时主函数的提示信息 增加 模板对 templates 目录的支持 增加 SerializationConfig,为渲染器提供统一的配置帮助 增加 ContextPathFilter 与 cfg().serverContextPath 配置同步 增加 应用属性配置内部引用增加默认值支持及环境变量引用 增加 @ProxyComponent 注解,使用时强依赖于 solon.proxy 插件 增加 @SolonMain 主解,作为 apt 生成 Graalvm Native 元信息配置的入口 增加 apt 代理实现方式(做为 asm 实现的补充),为全功能实现 Graalvm Native 打包提供支持 增加 InitializingBean 接口 增加 LifecycleBean 接口,扩展自 InitializingBean 和 Lifecycle 增加 ClassUtil 工具类 sqltoy 升级为 5.2.37 项目仓库: gitee:https://gitee.com/noear/solon github:https://github.com/noear/solon

优秀的个人博客,低调大师

Canonical 向 Plymouth 上游贡献改进,已用于 Ubuntu 20.04

安装 Ubuntu 20.04 系统的台式机/笔记本在 UEFI 模式下启动时,与旧版本最明显的区别之一就是启动界面的改进。这要归功于 Red Hat 在提供无闪烁(flicker-free)的启动体验方面所做的工作,并在启动过程中引入 UEFI BGRT 系统/主板 Logo,以提供更多的过渡体验。同样的,Canonical 也在努力贡献自己实现的一些改进并 push 给上游的 Plymouth。 过去一年来,Ubuntu 20.04 已拥有与 Fedora 和其他 Linux 发行版(如 Arch Linux)相似的的启动体验。 在此过程中,Ubuntu 开发者一直在对这个图形化的启动界面代码进行进一步打磨,其中包括 Canonical 的 Daniel van Vugt,他在过去几年里对 GNOME 上游的贡献是众所周知的。 开发者贡献的代码包括修复部分标签的居中问题、新的完整性检查模式(integrity-check mode),以及支持显示 fsck 状态信息。 这些工作也对 Red Hat 最近贡献的其他改进进行了补充,其中包括DRM/KMS 探针加速(probe speed-ups)和其他工作。

优秀的个人博客,低调大师

『并发包入坑指北』之向大佬汇报任务

前言 在面试过程中聊到并发相关的内容时,不少面试官都喜欢问这类问题: 当 N 个线程同时完成某项任务时,如何知道他们都已经执行完毕了。 这也是本次讨论的话题之一,所以本篇为『并发包入坑指北』的第二篇;来聊聊常见的并发工具。 <!--more--> 自己实现 其实这类问题的核心论点都是:如何在一个线程中得知其他线程是否执行完毕。 假设现在有 3 个线程在运行,需要在主线程中得知他们的运行结果;可以分为以下几步: 定义一个计数器为 3。 每个线程完成任务后计数减一。 一旦计数器减为 0 则通知等待的线程。 所以也很容易想到可以利用等待通知机制来实现,和上文的『并发包入坑指北』之阻塞队列的类似。 按照这个思路自定义了一个 MultipleThreadCountDownKit 工具,构造函数如下: 考虑到并发的前提,这个计数器自然需要保证线程安全,所以采用了 AtomicInteger。 所以在初始化时需要根据线程数量来构建对象。 计数器减一 当其中一个业务线程完成后需要将这个计数器减一,直到减为0为止。 /** * 线程完成后计数 -1 */ public void countDown(){ if (counter.get() <= 0){ return; } int count = this.counter.decrementAndGet(); if (count < 0){ throw new RuntimeException("concurrent error") ; } if (count == 0){ synchronized (notify){ notify.notify(); } } } 利用 counter.decrementAndGet() 来保证多线程的原子性,当减为 0 时则利用等待通知机制来 notify 其他线程。 等待所有线程完成 而需要知道业务线程执行完毕的其他线程则需要在未完成之前一直处于等待状态,直到上文提到的在计数器变为 0 时得到通知。 /** * 等待所有的线程完成 * @throws InterruptedException */ public void await() throws InterruptedException { synchronized (notify){ while (counter.get() > 0){ notify.wait(); } if (notifyListen != null){ notifyListen.notifyListen(); } } } 原理也很简单,一旦计数器还存在时则会利用 notify 对象进行等待,直到被业务线程唤醒。 同时这里新增了一个通知接口可以自定义实现唤醒后的一些业务逻辑,后文会做演示。 并发测试 主要就是这两个函数,下面来做一个演示。 初始化了三个计数器的并发工具 MultipleThreadCountDownKit 创建了三个线程分别执行业务逻辑,完毕后执行 countDown()。 线程 3 休眠了 2s 用于模拟业务耗时。 主线程执行 await() 等待他们三个线程执行完毕。 通过执行结果可以看出主线程会等待最后一个线程完成后才会退出;从而达到了主线程等待其余线程的效果。 MultipleThreadCountDownKit multipleThreadKit = new MultipleThreadCountDownKit(3); multipleThreadKit.setNotify(() -> LOGGER.info("三个线程完成了任务")); 也可以在初始化的时候指定一个回调接口,用于接收业务线程执行完毕后的通知。 当然和在主线程中执行这段逻辑效果是一样的(和执行 await() 方法处于同一个线程)。 CountDownLatch 当然我们自己实现的代码没有经过大量生产环境的验证,所以主要的目的还是尝试窥探官方的实现原理。 所以我们现在来看看 juc 下的 CountDownLatch 是如何实现的。 通过构造函数会发现有一个 内部类 Sync,他是继承于 AbstractQueuedSynchronizer ;这是 Java 并发包中的基础框架,都可以单独拿来讲了,所以这次重点不是它,今后我们再着重介绍。 这里就可以把他简单理解为提供了和上文类似的一个计数器及线程通知工具就行了。 countDown 其实他的核心逻辑和我们自己实现的区别不大。 public void countDown() { sync.releaseShared(1); } public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { doReleaseShared(); return true; } return false; } 利用这个内部类的 releaseShared 方法,我们可以理解为他想要将计数器减一。 看到这里有没有似曾相识的感觉。 没错,在 JDK1.7 中的 AtomicInteger 自减就是这样实现的(利用 CAS 保证了线程安全)。 只是一旦计数器减为 0 时则会执行 doReleaseShared 唤醒其他的线程。 这里我们只需要关心红框部分(其他的暂时不用关心,这里涉及到了 AQS 中的队列相关),最终会调用 LockSupport.unpark 来唤醒线程;就相当于上文调用 object.notify()。 所以其实本质上还是相同的。 await 其中的 await() 也是借用 Sync 对象的方法实现的。 public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); //判断计数器是否还未完成 if (tryAcquireShared(arg) < 0) doAcquireSharedInterruptibly(arg); } protected int tryAcquireShared(int acquires) { return (getState() == 0) ? 1 : -1; } 一旦还存在未完成的线程时,则会调用 doAcquireSharedInterruptibly 进入阻塞状态。 private final boolean parkAndCheckInterrupt() { LockSupport.park(this); return Thread.interrupted(); } 同样的由于这也是 AQS 中的方法,我们只需要关心红框部分;其实最终就是调用了 LockSupport.park 方法,也就相当于执行了 object.wait() 。 所有的业务线程执行完毕后会在计数器减为 0 时调用 LockSupport.unpark 来唤醒线程。 等待线程一旦计数器 > 0 时则会利用 LockSupport.park 来等待唤醒。 这样整个流程也就串起来了,它的使用方法也和上文的类似。 就不做过多介绍了。 实际案例 同样的来看一个实际案例。 在上一篇《一次分表踩坑实践的探讨》提到了对于全表扫描的情况下,需要利用多线程来提高查询效率。 比如我们这里分为了 64 张表,计划利用 8 个线程来分别处理这些表的数据,伪代码如下: CountDownLatch count = new CountDownLatch(64); ConcurrentHashMap total = new ConcurrentHashMap(); for(Integer i=0;i<=63;i++){ executor.execute(new Runnable(){ @Override public void run(){ List value = queryTable(i); total.put(value,NULL); count.countDown(); } }) ; } count.await(); System.out.println("查询完毕"); 这样就可以实现所有数据都查询完毕后再做统一汇总;代码挺简单,也好理解(当然也可以使用线程池的 API)。 总结 CountDownLatch 算是 juc 中一个高频使用的工具,学会和理解他的使用会帮助我们更容易编写并发应用。 文中涉及到的源码: https://github.com/crossoverJie/JCSprout/blob/master/src/main/java/com/crossoverjie/concurrent/communication/MultipleThreadCountDownKit.java 你的点赞与分享是对我最大的支持

优秀的个人博客,低调大师

数据分析向云迁移时如何避免混乱

【大咖・来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》 组织在将商业智能(BI)和数据分析业务迁移到云端时,需要将现有分析流程、软件评估、数据保护和成本控制纳入一个深思熟虑的行动计划中。这是因为必须考虑许多问题:检查现有的分析流程、选择正确的云计算工具、保护信息、确保数据质量,而最重要的是设立精心设计的目标。 云计算提供了内部替代方案难以比拟的优势——更灵活、更快的开发和部署新技术,以及更大的潜在成本节约。SAP公司商业智能(BI)和混合分析产品营销总监Steve McHugh说:“大多数成功将业务迁移到云端的组织都有明确的愿景和战略,他们希望商业智能(BI)和分析在他们的智能企业中发挥作用。这对他们来说是一种创新,并不一定是将他们目前的业务转移到云端,尽管一些企业对此很感兴趣。” 采用实验思维 企业需要意识到,在云中的数据分析不仅是为了节约成本,还涉及新的可能性。云计算服务公司Candid Partners公司顾问Mitch Gibbs说:“通过访问可扩展、稳定的基础设施而无需维护它们的开销,企业可以扩展到当时所需的分析水平,同时级及将实验的启动成本降到***。” 他建议分析经理将资源投入到实验过程中,以确定提供***回报的分析方法,并对其进行投资。Gibbs建议道,“企业不要将分析视为应用程序的一次性构建。与其相反,需要设计其系统和流程,以便随着业务需求的变化而发展。” 下一步是为云中的数据分析设定有价值的、可实现的目标,例如降低商业智能(BI)和分析成本、加快查询速度、提高用户并发性、提高决策支持的质量,以及自动提供数据驱动的业务流程洞察力。SiliconAngle Media公司***分析师James Kobielus说,“如果组织不能很好地确定想要实现的目标,就不要将其商业智能/分析工具从内部平台迁移出去。” 有许多基于SaaS的商业智能(BI)和分析工具需要考虑,它们在功能、价格、性能、地理可用性、行业和应用程序方面都有广泛的应用。设定目标有助于创建提供者的候选名单,以便在迁移计划的早期阶段实现目标。Kobielus说,“在决定哪一个将是组织的迁移目标之前,对这些提供商和产品功能进行尽职调查比较评估。组织决定是否只是在移动运营报告,或者是否也在将预测建模、数据挖掘、机器学习和其他高级分析应用程序迁移到云端,这一点很重要。” Kobielus指出,为迁移项目做准备,这可能会花费比预期更长的时间和更高的成本。如果迁移许多数据库和大量需要为云计算从头开始重新构建的分析集合,其项目可能会更加复杂。 在确定迁移专业知识和选择工具时,有以下一些重要注意事项: 组织是在迁移每个遗留的商业智能(BI)和分析应用程序,还是计划在迁移过程中取消许多未充分利用的应用程序? 组织是否有必要的内部专业知识和工具来进行正确地迁移,或者组织是否需要聘请顾问? 目标云平台的提供商是否具有专业服务和工具来帮助组织迁移? 审核现有的数据管理实践 人工智能数据管理平台Immuta公司云计算业务总经理Rob Lancaster说,“评估现有数据周围的数据管理基础设施和安全性非常重要。我们看到的一个主要问题是,数据传统上是由本地系统进行保护的,这些系统在云中是不存在的。很多组织意识到,一旦他们将数据迁移到云端,就不能像以前那样保护它,需要考虑不同且更灵活的策略来实现真正的数据分析,但已经太晚了。” 日志管理和安全分析公司SumoLogic公司产品营销总监Ben Newton表示:“我们应该注意到以往数据库的损坏。人们常常沉迷于收集数据而不是回答问题。” 企业在将数据迁移到云端之前,需要清楚地概述一些关键业务问题,并确定数据以回答这些问题。更好的是,选择一个特定的应用程序或业务领域作为开始。“不要试图处理整个数据湖。而是从一个数据池开始。”Newton建议说。他表示,他经常遇到企业在不反映实际情况的数据集上构建业务战略。为了使云计算中的数据分析取得成功,企业需要了解非结构化、结构化和半结构化数据分析的基本细节。这将使开发一种策略更容易,以满足传统、运行良好的商业智能(BI)工具和机器数据分析的需求。 Zendesk公司产品战略副总裁Sam Boonin说:“***从云中可能存在的数据开始,例如数字客户旅程数据或与现有SaaS投资相关的数据。”这将有助于获得一些快速并熟悉基于云计算的商业智能(BI)环境。然后,将云计算转换计划构建到整体商业智能(BI)策略中,并随时间的推移迁移其余数据。 通常,商业智能(BI)面临的主要挑战是访问、清理和规范化数据。云计算使这些任务更容易,因为很多数据已经存在于AWS和Microsoft Azure等公共云中。但Boonin强调,企业的“数据管道”仍然需要一致的治理和IT工作。 控制数据和成本 越来越多的人担心云中的数据分析,尤其是通用数据保护规范(GDPR)等新法规,在迁移过程中会保护敏感信息。需要屏蔽或标记敏感数据。 数据隐私服务商BigID公司的联合创始人兼***产品官Nimrod Vax表示,“数据的物理位置也是一个问题。由于组织无法始终了解或控制云计算提供商存储数据的位置,因此可能会无意中违反数据驻留法规。组织不仅需要知道他们的数据存储位置,还需要知道他们存储的数据。”他指出,那些能够在迁移到云之前映射数据的用户将更好地了解正在迁移的数据类型。 云计算定价可能很有吸引力,似乎是一个简单的切入点,但其成本可能无法预测。运营数据库管理系统提供商MarkLogic公司产品执行副总裁Joe Pasqua表示,“很多组织都无法准确估算成本。” 对云中的商业智能(BI)和数据分析而言,成本估算尤其具有挑战性。虽然运营工作负载通常由可重复的业务流程驱动,这可以使它们更具可预测性,但商业智能(BI)和分析可能受到用户和数据科学家的推动。Pasqua说,“总有一些分析要做,而采用云计算使得消耗更多资源变得非常容易。使用能够有效分析使用模式并控制使用情况的平台获得可预测的成本,这一点非常重要。”

优秀的个人博客,低调大师

拒向 MongoDB 妥协,AWS 推出替代品 DocumentDB

【大咖・来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》 AWS 昨日宣布推出DocumentDB,这是一个与 MongoDB API 兼容的新数据库产品。AWS 将 DocumentDB 描述为“一个快速、可扩展且高度可用的文档数据库,旨在与你现有的 MongoDB 应用和工具兼容”。实际上,它是一个 MongoDB 的托管版简易替代品,不使用任何 MongoDB 代码。 AWS 表示,尽管 MongoDB 在功能方面做得很好,但由于大规模设置和管理 MongoDB 集群所带来的复杂性,用户很难构建那些可扩展到每秒数 TB 和数十万次读写操作的高性能应用。Amazon DocumentDB 则是从头开始设计,可为用户提供大规模运行任务关键型(mission-critical)MongoDB 工作负载所需的性能、可扩展性和可用性,且与 Apache 2.0 开源 MongoDB 3.6 API 兼容。 话虽如此,但联想到MongoDB 去年10月因不满云供应商滥用行为而修改开源协议的动作,AWS 此举就显得耐人寻味了。 外媒TechCrunch写道:DocumentDB 就是 AWS 做的 MongoDB 替代品,长期以来,AWS 一直被指责采用优质的开源项目进行再利用和品牌再塑,但又不总是回馈这些社区,这早已不是什么秘密。MongoDB 也是最早通过更换许可证去阻止这种情况的公司之一,新许可证明确表示,想要这样坐享其成的公司必须购买商业许可证。之后,其他开源公司也纷纷效仿。 TechCrunch 还就此联系了 MongoDB 的 CEODev Ittycheria,他表示: 模仿就是最真诚的奉承,所以 AWS 此举并不奇怪。不过,开发者在技术上都足够精明,能够区分真实的创新和差劲的模仿。MongoDB 将继续超越市场中的任意模仿者。 MongoDB 的联合创始人兼 CTO Eliot Horowitz 对此表示赞同,他说: “为了给开发者想要的东西,AWS 已经被要求提供基于两年前的 MongoDB 代码仿制MongoDB 服务。我们整个公司都专注于一件事 —— 为开发者提供处理数据的***方式,且可以随意运行。我们致力于实现此目标,这将继续使真正的 MongoDB 有别于那些不断出现的模仿品。” MongoDB 的发言人也补充道,DocumentDB 兼容的 MongoDB 3.6 API 已有两年的历史,缺失太多新的功能,比如ACID 事务、全局集群和移动同步。 TechCrunch ***写道:客观地说,AWS 最近在开源社区变得更加活跃了,并且从某种程度上来说,它确实为开发者提供了他们想要的东西(并非所有开发者都对 MongoDB 自己的托管服务感到满意)。但考虑到 AWS 在已经明确知道 MongoDB 更换许可证的原因的情况下,还是选择用兼容老版本 API 的形式绕过 MongoDB 的新许可,这始终就是一个有争议的举动,且不会让这家公司受到开源社区的喜爱。

优秀的个人博客,低调大师

循环定时向qq对话框中发送消息

在qq中重复发消息,利用网上的操作代码,自己定义了一个类,用多线程和定时实现对一个qq弹窗循环定时发消息。https://github.com/Wn-Dev/qq_send_messages # 原理是先将需要发送的文本放到剪贴板中,然后将剪贴板内容发送到qq窗口 # 之后模拟按键发送enter键发送消息 import win32gui import win32con import win32clipboard as w import time import threading class SendMessage: to_who ='' msg='' def __init__(self,t,m): self.to_who = t self.msg = m def getText(self): """获取剪贴板文本""" w.OpenClipboard() d = w.GetClipboardData(win32con.CF_UNICODETEXT) w.CloseClipboard() return d def setText(self): """设置剪贴板文本""" w.OpenClipboard() w.EmptyClipboard() w.SetClipboardData(win32con.CF_UNICODETEXT,self.msg) w.CloseClipboard() def send_qq(self): """发送qq消息 to_who:qq消息接收人 msg:需要发送的消息 """ # 将消息写到剪贴板 self.setText() # 获取qq窗口句柄 qq = win32gui.FindWindow(None, self.to_who) # 投递剪贴板消息到QQ窗体 win32gui.SendMessage(qq, 258, 22, 2080193) win32gui.SendMessage(qq, 770, 0, 0) # 模拟按下回车键 win32gui.SendMessage(qq, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0) win32gui.SendMessage(qq, win32con.WM_KEYUP, win32con.VK_RETURN, 0) # def display(self): # print(self.to_who) if __name__ =='__main__': num=0 #msg:你想输入的消息 msg='' #to_who_x: 用于qq的消息窗口 to_who_1 = "" to_who_2 ="" m1 = SendMessage(to_who_1,msg) m2 = SendMessage(to_who_2,msg) while True: t1= threading.Thread(target= m1.send_qq()) t2= threading.Thread(target= m2.send_qq()) t1.start t1.join t2.start t2.join print(num) num=num+1 time.sleep(30)

优秀的个人博客,低调大师

Akka向设备组添加Actor注册《thirteen》译

我们已经完成了设备级别的注册支持,现在我们必须在组级别实现它。在注册时,小组成员还有更多工作要做,包括: 通过将注册请求转发给现有设备actor或通过创建新actor并转发消息来处理注册请求。 跟踪组中存在哪些设备Actor,并在组停止时从组中删除它们。 处理注册请求 设备组Actor必须将请求转发给现有子项,或者应创建一个。要通过设备ID查找子actor,我们将使用Map <String,ActorRef>。 我们还希望保留请求的原始发件人的ID,以便我们的设备角色可以直接回复。这可以通过使用forward而不是tell运算符来实现。两者之间的唯一区别是,forward会保留原始发件人,而tell会将发件人设置为当前的actor。就像我们的设备actor一样,我们确保不会响应错误的组ID。将以下内容添加到源文件中: Full source at GitHub 正如我们对设备所做的那样,我们测试了这个新功能。我们还测试了返回两个不同ID的Actor实际上是不同的,我们还尝试记录每个设备的温度读数,以查看Actor是否正在响应。 Full source at GitHub 如果注册请求已存在设备actor,我们希望使用现有的actor而不是新的actor。我们还没有测试过,所以我们需要解决这个问题: Full source at GitHub 跟踪组中的设备Actor 到目前为止,我们已经实现了在组中注册设备actor的逻辑。然而,设备来来去去,所以我们需要一种从Map <String,ActorRef>中删除设备actor的方法。我们将假设当移除设备时,其相应的设备actor将停止。正如我们前面讨论的那样,监督只处理错误情况 - 不是优雅的停止。因此,我们需要在其中一个设备actor停止时通知父级。 Akka提供死亡观察功能,允许Actor观看另一个Actor,并在其他Actor停止时收到通知。与监督不同,观看不仅限于父子关系,任何Actor都可以观看任何其他Actor,只要它知道ActorRef即可。在观看的Actor停止之后,观察者接收终止(actorRef)消息,该消息还包含对观看的Actor的引用。观察者可以显式处理此消息,也可以使用DeathPactException失败。如果Actor在观看Actor停止后不再履行自己的职责,后者就很有用。在我们的例子中,该组在一个设备停止后仍然应该起作用,因此我们需要处理Terminated(actorRef)消息。 我们的设备组Actor需要包含以下功能: 在创建新设备Actor时开始观察它们。 当通知指示已停止时,从Map <String,ActorRef>中删除设备actor,该设备actor将设备映射到设备actor。 不幸的是,Terminated消息只包含子actor的ActorRef。我们需要actor的ID将其从现有设备的映射中移除到设备actor映射。为了能够执行此删除,我们需要引入另一个占位符Map <ActorRef,String>,它允许我们找出与给定ActorRef对应的设备ID。 添加识别actor的功能实现: Full source at GitHub 到目前为止,我们无法获得组设备主体跟踪的设备,因此,我们无法测试我们的新功能。为了使其可测试,我们添加了一个新的查询功能(消息RequestDeviceList),列出了当前活动的设备ID: Full source at GitHub 我们几乎准备好测试设备的移除。但是,我们仍然需要以下功能: 从我们的测试用例中停止设备actor。从外面看,任何Actor都可以通过发送特殊的内置消息PoisonPill来停止,该消息指示Actor停止。 在设备actor停止后收到通知。我们也可以将Death Watch设施用于此目的。TestKit有两个我们可以轻松使用的消息,watch()来监视一个特定的actor,而expectTerminated断言被监视的actor已被终止。 我们现在再添加两个测试用例。首先,我们测试一旦添加了几个设备,我们就会返回正确的ID列表。第二个测试用例确保在设备actor停止后正确删除设备ID: Full source at GitHub 创建设备管理器角色 要进入层次结构中的下一个级别,我们需要在DeviceManager源文件中为设备管理器组件创建入口点。此actor与设备组actor非常相似,但是创建设备组actor而不是设备actor: Full source at GitHub 我们将设备管理器的测试留作练习,因为它与我们为组Actor编写的测试非常相似 What’s next? 我们现在有一个分层组件,用于注册和跟踪设备和记录测量。我们已经了解了如何实现不同类型的会话模式,例如: Request-respond(用于温度记录) Delegate-respond(用于设备注册) Create-watch-terminate(用于创建组和设备actor作为子项) 在下一章中,我们将介绍组查询功能,它将建立一个新的分散 - 聚集对话模式。特别是,我们将实现允许用户查询属于组的所有设备的状态的功能。 下节再续! 原文:https://doc.akka.io/docs/akka/2.5/guide/tutorial_4.html 有什么讨论的内容,可以加我公众号:

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册