做做网站下载2023八戒电影在线观看免费7

pingmian/2026/1/21 12:46:38/文章来源:
做做网站下载2023,八戒电影在线观看免费7,双语 网站 数据怎么做,上传照片的网站赚钱Guava是Google开源的一个Java基础类库#xff0c;它在Google内部被广泛使用。Guava提供了很多功能模块比如#xff1a;集合、并发库、缓存等#xff0c;EventBus是其中的一个module#xff0c;本篇结合EventBus源码来谈谈它的设计与实现。 概要 首先#xff0c;我们先来预… Guava是Google开源的一个Java基础类库它在Google内部被广泛使用。Guava提供了很多功能模块比如集合、并发库、缓存等EventBus是其中的一个module本篇结合EventBus源码来谈谈它的设计与实现。 概要 首先我们先来预览一下EventBus模块的全部类图 类并不是多而且几乎没有太多继承关系。 下面我们来看一下各个类的职责 EventBus核心类代表了一个事件总线。Publish事件也由它发起。AsyncEventBus在分发事件的时候将其压入一个全局队列的异步分发模式。Subscriber对某个事件的处理器抽象封装了事件的订阅者以及处理器并负责事件处理该类的类名及其语义有些不明确后续会谈到。SubscriberRegistry订阅注册表它用于存储Subscriber跟Event的对应关系以便于EventBus在publish一个事件时可以找到它对应的Subscriber。Dispatcher事件分发器它定义了事件的分发策略。Subscribe用于标识事件处理器的注解当EventBus publish一个事件后相应的Subscriber将会得到通知并执行事件处理器。AllowConcurrentEvents该注解跟Subscribe一同使用标识该订阅者的处理方法为线程安全的该注解还用于标识该方法将可能会被EventBus在多线程环境下执行。DeadEvent死信没有订阅者关注的事件对象。SubscribeExceptionHandler订阅者抛出异常的处理器。SubscribeExceptionContext订阅者抛出异常的上下文对象。在对每个类进行分解之前我们再来看一下各个类之间的关联关系 分“类”解读 EventBus 它有这么几个字段 identifier事件总线的标识这说明在一个应用里是可以有多个EventBus的。如果不指明它的值它将以“default”作为其默认名称。executor它是Executor接口的实例用于对订阅者处理事件方法的执行。这里需要注意的是该字段的实例化是在EventBus内部构造器中并不是从外部注入进来的另外真正的执行订阅者方法的时机也不由EventBus负责而是由Subscriber负责因此该字段会被公开给外部访问。exceptionHandler它是SubscribeExceptionHandler的实例用于处理订阅者在执行事件处理方法时抛出的异常。EventBus可以接收一个外部定义的异常处理器也可以采用内部缺省的日志记录处理器。subscribers订阅者注册表用于存储所有的事件以及事件处理器、订阅对象的对应关系。dispatcher事件分发器用于分发事件给订阅对象的事件处理器该对象在EventBus构造方法内部初始化默认的实现是PerThreadQueuedDispatcher该分发器将事件存入队列并保证在同一个线程上发送的事件能够按照他们发布的顺序被分发给所有的订阅者。EventBus提供了几个核心方法 register注册subscriberunregister移除注册过的subscriberpost发布事件 你可以将EventBus看做是一个代理这些方法真正的实现者都是上面的这些对象。 AsyncEventBus 一个支持异步发布模式的EventBus它覆盖了EventBus的默认构造方法指定了一个异步的分发器LegacyAsyncDispatcher这个分发器基于一个全局的队列来暂存未发布的事件。 Subscriber 之前也提到Subscriber的名称是比较容易混淆的。这个类的名称看似表示一个订阅者对象但其实是用来封装“一个订阅者的一个事件处理器”对象。因为当一个订阅者存在多个处理方法被标注为Subscribe的时候那么每个处理方法都对应于一个独立的Subscriber对象的实例。我个人觉得这个名称与其具体的实现语义有些混淆。当然也许实现者认为一个对象以及一个事件处理器就是一个Subscriber的话那是没有问题的。因此这里为了理解方便你可以将其看做是一个封装了订阅者对象以及一个订阅者处理器方法的实体类。 Subscriber的访问级别是package的它还承担了执行事件处理的责任。通过一个create静态工厂方法创建它 static Subscriber create(EventBus bus, Object listener, Method method) {return isDeclaredThreadSafe(method)? new Subscriber(bus, listener, method): new SynchronizedSubscriber(bus, listener, method);} 它接收三个参数 busEventBus的实例通过它来获取事件的执行器executorlistener真实的订阅者对象method订阅对象的事件处理方法的Method实例在实现中它会先判断该处理器方法上是否被标注有AllowConcurrentEvents注解如果有则实例化Subscriber类的一个实例如果没有则不允许eventbus在多线程的环境中调用处理器方法所以这里专门为此提供了一个同步的订阅者对象SynchronizedSubscriber来保证线程安全。 该类的两个关键方法之一 dispatchEvent: final void dispatchEvent(final Object event) {executor.execute(new Runnable() {Overridepublic void run() {try {invokeSubscriberMethod(event);} catch (InvocationTargetException e) {bus.handleSubscriberException(e.getCause(), context(event));}}});} 它调用一个多线程执行器来执行事件处理器方法。 另一个方法invokeSubscriberMethod以反射的方式调用事件处理器方法。 另外该类对Object的equals方法进行了override并标识为final。主要是为了避免同一个对象对某个事件进行重复订阅在SubscriberRegistry中会有相应的判等操作。当然这里Subscriber也override并final了hashCode方法。这是最佳实践不必多谈如果不了解的可以去看看《Effective Java》。 该类还有个内部类就是我们上面谈到的SynchronizedSubscriber它继承了Subscriber与Subscriber唯一的不同就是在invokeSubscriberMethod的执行上做了同步。 SubscriberRegistry 针对单个EventBus的订阅与事件的关系维护。在内部用来存储订阅者关系的对象是java并发包下的并发Map:ConcurrentMap该map以Class对象为键值的类型是CopyOnWriteArraySetSubscriber集合类型。 SubscriberRegistry直接依赖EventBus对象所以在构造器中需要注入EventBus的实例。 SubscriberRegistry里有两个关键的实例方法register/unregister。 register 接收订阅者对象作为参数并建立Event跟Subscriber的关联关系。 我们来看看它的实现 void register(Object listener) {MultimapClass?, Subscriber listenerMethods findAllSubscribers(listener);for (Map.EntryClass?, CollectionSubscriber entry : listenerMethods.asMap().entrySet()) {Class? eventType entry.getKey();CollectionSubscriber eventMethodsInListener entry.getValue();CopyOnWriteArraySetSubscriber eventSubscribers subscribers.get(eventType);if (eventSubscribers null) {CopyOnWriteArraySetSubscriber newSet new CopyOnWriteArraySetSubscriber();eventSubscribers MoreObjects.firstNonNull(subscribers.putIfAbsent(eventType, newSet), newSet);}eventSubscribers.addAll(eventMethodsInListener);}} 它首先获得一个Multimap实例它是Google Guava集合框架提供的一个多值Map类型也就是说一个key可以对应多个value该Multimap用于存储事件类型对应的该订阅者内所有关于该事件的处理器方法集合其key为事件的Class类型。这里在for循环的中通过asMap获取其map视图即可将Multimap对应的多个值存储到一个Collection中。 也就是说这里for循环的每个entry表示的是一个事件的Class实例对应的一组Subscriber的集合即eventMethodsInListener。 然后根据该事件的Class对象从注册表中获取对应的存储Subscriber实例的集合如果不存在则创建该集合然后将该订阅者内所有的事件处理器方法都加入到注册表中去。 unregister unregister的实现跟register有些类似先查找该订阅者所有的事件类型与处理器的对应关系。然后遍历所有的事件类型移除针对当前订阅者的所有Subscriber实例。 findAllSubscribers register/unregister方法都调用了findAllSubscribers方法它有一些特别之处这里需要单独拎出来提一下。 findAllSubscribers用于查找事件类型以及事件处理器的对应关系。查找注解需要涉及到反射通过反射来获取标注在方法上的注解。因为Guava针对EventBus的注册采取的是“隐式契约”而非接口这种“显式契约”。而类与接口是存在继承关系的所有很有可能某个订阅者其父类或者父类实现的某个接口也订阅了某个事件。因此这里的查找需要顺着继承链向上查找父类的方法是否也被注解标注代码实现 private MultimapClass?, Subscriber findAllSubscribers(Object listener) {MultimapClass?, Subscriber methodsInListener HashMultimap.create();Class? clazz listener.getClass();for (Method method : getAnnotatedMethods(clazz)) {Class?[] parameterTypes method.getParameterTypes();Class? eventType parameterTypes[0];methodsInListener.put(eventType, Subscriber.create(bus, listener, method));}return methodsInListener;} 同样涉及这个问题的还有根据事件类型获取Subscriber实例的方法getSubscribers。 getSubscribers IteratorSubscriber getSubscribers(Object event) {ImmutableSetClass? eventTypes flattenHierarchy(event.getClass());ListIteratorSubscriber subscriberIterators Lists.newArrayListWithCapacity(eventTypes.size());for (Class? eventType : eventTypes) {CopyOnWriteArraySetSubscriber eventSubscribers subscribers.get(eventType);if (eventSubscribers ! null) {// eager no-copy snapshotsubscriberIterators.add(eventSubscribers.iterator());}}return Iterators.concat(subscriberIterators.iterator());} Dispatcher dispatcher用于分发事件给Subscriber。它内部实现了多个分发器用于提供在不同场景下不同的事件顺序性。Dispatcher是一个抽象类定义了一个核心抽象方法 abstract void dispatch(Object event, IteratorSubscriber subscribers); 该方法用于将一个指定的事件分发给所有的订阅者。 另外在Dispatcher提供了三个不同的分发器实现 PerThreadQueuedDispatcher 它比较常用针对每个线程构建一个队列用于暂存事件对象。保证所有的事件都按照他们publish的顺序从单一的线程上发出。保证从单一线程上发出没什么特别的地方主要是在内部定义了一个队列将其放在ThreadLocal中用以跟特定的线程关联。 LegacyAsyncDispatcher 另一个异步分发器的实现LegacyAsyncDispatcher之前在介绍AsyncEventBus的时候提到它就是用这种实现来分发事件。 它在内部通过一个ConcurrentLinkedQueueEventWithSubscriber的全局队列来存储事件。从关键方法dispatch的实现来看它跟PerThreadQueuedDispatcher的区别主要是两个循环上的差异这里基于队列的缓存事件的方式肯定会存在两个循环循环取队列里的事件以及循环发送给Subscriber。 PerThreadQueuedDispatcher是两层嵌套循环外层是遍历队列取事件内存是遍历事件的订阅处理器。 LegacyAsyncDispatcher是一前一后两个循环。前面一个是遍历事件订阅处理器并构建一个事件实体对象存入队列。后一个循环是遍历该事件实体对象队列取出事件实体对象中的事件进行分发。 ImmediateDispatcher 其实以上两个基于中间队列的分发实现都可以看做是异步模式而ImmediateDispatcher则是同步模式只要有事件发生就会立即分发并被立即得到处理。ImmediateDispatcher从感官上看类似于线性并顺序执行而采用队列的方式有多线程汇聚到一个公共队列的由发散到聚合的模型。因此ImmediateDispatcher的分发方式是一种深度优先的方式而使用队列是一种广度优先的方式。 DeadEvent 它是一个实体对象封装了没有订阅者的事件。DeadEvent由两个属性组成 source事件源通常指发布事件的EventBus对象event事件对象DeadEvent对象的产生当通过某个EventBus的实例发布一个事件的时候没有找到事件订阅者并且它本身又不是一个DeadEvent的实例时将由EventBus构建一个DeadEvent类的实例。 总结 Guava的EventBus源码还是比较简单、清晰的。从源码来看它一番常用的Observer的设计方式放弃采用统一的接口、统一的事件对象类型。转而采用基于注解扫描的绑定方式。 其实无论是强制实现统一的接口还是基于注解的实现方式都是在构建一种关联关系或者说满足某种契约。很明显接口的方式是编译层面上强制的显式契约而注解的方式则是运行时动态绑定的隐式契约关系。接口的方式是传统的方式编译时确定观察者关系清晰明了但通常要求有一致的事件类型、方法签名。而基于注解实现的机制刚好相反编译时因为没有接口的语法层面上的依赖关系显得不那么清晰至少静态分析工具很难展示观察者关系但无需一致的方法签名、事件参数至于多个订阅者类之间的继承关系可以继承接收事件的通知可以看作既是其优点也是其缺点。 原文发布时间为2015-06-01 本文作者vinoYang 本文来自云栖社区合作伙伴CSDN博客了解相关信息可以关注CSDN博客。

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

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

相关文章

重点实验室网站建设今天新闻摘抄十条

图像的表示 1,位数 计算机采用0/1编码的系统,数字图像也是0/1来记录信息,图像都是8位数图像,包含0~255灰度, 其中0代表最黑,1代表最白 3, 4,OpenCV部署方法 安装OpenCV之前…

江门网站建设推广公司的网站建设价格

目录 前言 一、动态树的实现 1.数据表 2.编写后端controller层 3.定义前端发送请求路径 4.前端左侧动态树的编写 4.1.发送请求获取数据 4.2.遍历左侧菜单 5.实现左侧菜单点击展示右边内容 5.1.定义组件 5.2.定义组件与路由的对应关系 5.3.渲染组件内容 5.4.通过动态…

宣城市网站集约化建设西安建公司网站

目的 Q:如何在Qt库的基础上,实现自定义控件呢? A:根据官方文档回答,就是继承需实现的控件,然后实现自定义功能。 以下是实现QListWidget控件的自定义item。 先看下最终效果是如何: listItem 主…

临沂建设工程招聘信息网站郑州网站建设 .cc

1. 什么是bug bug本意是昆虫”或“虫子”,现在一般是指在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问 题,简称程序漏洞。 “Bug” 的创始人格蕾丝赫柏(Grace Murray Hopper),她是一位为美国海军工作的…

实名制认证网站wordpress主题git下载失败

统一建模语言(Unified Modeling Language, UML )是一种为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言,是非专利的第三代建模和规约语言。 UML 是面向对象设计的建模工具,独立于任何具体程序设计语言。 一、简介 UML 作为一…

网站为什么做优化ppt百度引擎搜索网址

Nacos与Eureka的区别详解 在微服务架构中,服务注册与发现是核心组件之一,它们允许服务实例在启动时自动注册,并且能被其他服务发现,从而实现服务之间的互相通信。Nacos和Eureka都是现代微服务体系中广泛使用的服务注册与发现工具。本文将深入分析二者的区别,并为您提供一…

槐荫区网站建设室内装修设计软件用哪个好

在今年夏天策马翻译举办的翻译讲座上,我和詹成教授交流过一个问题:詹教授讲的很多知识点和经验并不符合“信达雅”?詹教授的回答是:“信达雅”并非翻译界的标准,他自己在日常翻译工作中的标准是“快准顺”。詹教授的回…

商务网站设计服务外包公司是干什么的

📚 目录 介绍布局原理和约束盒模型布局 约束容器ConstrainedBox非约束容器UnconstrainedBox 线性布局 行row列column 弹性布局流式布局 WrapFlow 层叠布局对齐和相对定位布局构建回调 LayoutBuilder布局过程中AfterLayout布局完成后执行 本文学习和引用自《Flutte…

天津专业做网站网站内页制作

背景 > 经过检测,我们识别到您的应用,目前未适配安卓11(API30),请您关注适配截止时间,尽快开展适配工作,避免影响应用正常发布和经营。 > targetSdkVersion30 升级适配工作参考文档&am…

千万pv网站开发成本网上做网站怎么赚钱

部署网站 说好不哭 在接触serverless架构之前,我们如果想实现上线一个Web网站,就要在开发前期经过操作很多冗杂但又必须的步骤,不少小白可谓是快速的从入门到退坑。 编写代码,部署应用,部署数据库,申请域…

国外主流网站开发技术丽江建设信息网站

容器化是最近几年 DevOps 界流行的趋势,通过业务的容器化我们将创建一个完全打包、自包含的计算环境,让软件开发人员能够更加快速地创建和部署自己的应用程序。然而长期以来,由于镜像格式的限制,容器启动镜像的加载是很慢的&#…

如何制作网页跳转链接关键词seo排名公司

今日内容 1. Junit单元测试 2. 反射 3. 注解Junit单元测试: * 测试分类:1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。2. 白盒测试:需要写代码的。关注程序具体的执行流程。* Junit使…

衡水移动网站建设价格中国最好的猎头公司

随着加密数字货币的交易方式逐渐完善,杠杆交易也逐渐成为交易者获利的重要手段之一。杠杆交易可以通过借贷放大投资收益,但是也同时放大风险。 实际使用过程中有很多小白会有不少疑问:比如杠杆交易和合约交易都是放大风险,那这两…

旅游网站的建设依据和背景哪个旅游网站可以做私人定制

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计,课程设计参考与学习用途。仅供学习参考, 不得用于商业或者非法用途,否则,一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

百度做网站联系电话怎么做一个好的wordpress

一、同源策略 同源策略(Same Origin Policy): 同源是指域名,协议,端口完成一致,那么这两个url就是同源。同源策略是一种约定,它是浏览器最核心也最基本的安全功能,也是浏览器故意设置的一个功能限制。如果缺少了同源策…

商城网站建设都有哪些类型阀门行业网站怎么做

1.集合 在内存层面需要针对于多个数据进行存储。此时可以考虑的容器有:数组、集合类。 数组存储多个数据方面的特点: 数组一旦初始化,其长度就是确定的。数组中的多个元素是依次紧密排列的,有序的,可重复的。数组一…

15年做那些网站能致富免费的高清视频素材网站

迅雷已经用了 10 年,一直把它看作是速度最快也最方便的下载工具。迅雷会员也是我必续的服务。但,迅雷堕落了。thunder: 迅雷专属链接越来越少,基本都是磁力、BT 的天下迅雷会员加速不再给力,大量资源速度为 0。会员虽然还有一年多…

目前网站建设用哪种语言公司注销后 网站备案吗

register方法正如前面所提到的,在register方法中只绑定事物到服务容器,而不要做其他事情,否则,一不小心就能用到一个尚未被加载的服务提供者提供的服务。现在让我们来看看一个基本的服务提供者长什么样:namespace AppP…

烟台北京网站建设公司哪家好wordpress博客背景

1. 问题描述 问题描述,现A表(用户查看实验的次数)有user_id和exp_id两个字段,其中user_id加exp_id不唯一。B表有user_id,exp_id以及exp_num三个字段,其中user_id加exp_id唯一(表中未建唯一索引)。 现需要将A表的数据同步到B表,单机模式通过定时任务同步。A表的数据有…

教育门户网站模板外贸小网站建设

【力扣】 209. 长度最小的子数组 文章目录 【力扣】 209. 长度最小的子数组1. 题目介绍2. 解法2.1 暴力求解2.2 前缀和 二分查找2.3 滑动窗口2.4 贪心回溯 3. Danger参考 1. 题目介绍 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 …