Google Guava EventBus和Java 7 WatchService用于事件编程

这篇文章将介绍如何使用Guava EventBus将更改发布到Java 7 WatchService检测到的目录或子目录中。 Guava EventBus是向应用程序添加发布/订阅通信的好方法。 Java 7 java.nio.file软件包中新增的WatchService用于监视目录中的更改。 由于EventBus和WatchService已在以前的文章中介绍过,因此我们在这里不会深入介绍这些主题。 有关更多信息,鼓励读者查看EventBus和WatchService帖子。 [注意:为清楚起见,帖子于2012年2月28日更新。]

为什么使用EventBus

将EventBus与WatchService一起使用的主要原因有两个。

  1. 我们不希望轮询事件,而是希望接收异步通知。
  2. 处理事件后,需要调用WatchKey.reset方法以使所有新更改都可以排队。 尽管WatchKey对象是线程安全的,但重要的是仅在所有线程完成处理事件之后才调用reset方法,这会导致一些协调麻烦。 使用单个线程处理事件,调用reset方法,然后通过EventBus发布更改,消除了此问题。

我们实现这一目标的计划很简单,将涉及以下步骤:

  1. 实例化WatchService的实例。
  2. 从给定的Path对象开始递归注册每个目录。
  3. 将事件从WatchService队列中移出,然后处理并发布这些事件。
  4. 启动一个单独的线程以使事件脱离队列并发布。

下面的代码示例是DirectoryEventWatcherImpl类中更相关的重点,它将完成所有这些工作。

在WatchService中注册目录

在添加或删除子目录时将生成事件,而监视目录的子目录进行的任何更改均不会。 我们将通过递归遍历所有子目录(通过Files.walkFileTree方法)并使用WatchService对象(在此示例中先前定义)注册每个子目录来对此进行补偿:

private void registerDirectories() throws IOException {Files.walkFileTree(startPath, new WatchServiceRegisteringVisitor());
}private class WatchServiceRegisteringVisitor extends SimpleFileVisitor<Path>{@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {dir.register(watchService,ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);return FileVisitResult.CONTINUE;}
}

在第2行,Files.walkFileTree方法使用在第5行定义的WatchServiceRegisteringVisitor类向WatchService注册每个目录。 所注册的事件是文件/目录的创建,文件/目录的删除或文件的更新。

发布事件

下一步是创建一个FutureTask,它将执行检查队列和发布事件的工作。

private void createWatchTask() {watchTask = new FutureTask<>(new Callable<Integer>() {private int totalEventCount;@Overridepublic Integer call() throws Exception {while (keepWatching) {WatchKey watchKey = watchService.poll(10, TimeUnit.SECONDS);if (watchKey != null) {List<WatchEvent<?>> events = watchKey.pollEvents();Path watched = (Path) watchKey.watchable();PathEvents pathEvents = new PathEvents(watchKey.isValid(), watched);for (WatchEvent event : events) {pathEvents.add(new PathEvent((Path) event.context(), event.kind()));totalEventCount++;}watchKey.reset();eventBus.post(pathEvents);}}return totalEventCount;}});}private void startWatching() {new Thread(watchTask).start();
}

在第7行,我们每10秒检查一次WatchService是否有排队事件。 当返回有效的WatchKey时,第一步是检索事件(第9行),然后获取发生事件的目录(第10行)。 在第11行,将创建一个PathEvents对象,该对象将一个布尔值和受监视的目录用作构造函数参数。 第12至15行使用目标Path和事件类型作为创建PathEvent对象的参数遍历第9行检索到的事件。 在第16行调用WatchKey.reset方法,将WatchKey状态设置回ready,使其有资格接收新事件并将其放回到队列中。 最后,在第17行,EventBus将PathEvents对象发布给所有订阅者。 重要的是在这里注意PathEvents和PathEvent类是不可变的。 从Callable返回的totalEventCount永远不会在API中公开,而是用于测试目的。 第25行的startWatching方法启动线程以运行上面定义的监视/发布任务。

结论

通过将WatchService与Guava EventBus配对,我们可以在单个线程中管理WatchKey并处理事件,并以异步方式通知任意数量的订阅者该事件。 希望读者发现此示例有用。 一如既往地欢迎提出意见和建议。

资源资源

    • 这篇文章的源代码和单元测试
    • EventBus API
    • WatchService API
    • WatchService上的上一篇文章 。
    • EventBus上的上一篇文章

参考: 事件编程示例:来自JCG合作伙伴 Bill Bejeck的Google Guava EventBus和Java 7 WatchService,来自“ 随机思考编码”博客。

翻译自: https://www.javacodegeeks.com/2012/12/google-guava-eventbus-and-java-7-watchservice-for-event-programming.html

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

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

相关文章

Bootstrap-table 部分浏览器显示不出来

一、问题 近日&#xff0c;写了一个ASP.Net项目&#xff0c;但是bootstrap-table在别人的电脑上显示不出来&#xff0c;在自己的电脑上能显示&#xff0c;有些浏览器也是能显示&#xff0c;但部分浏览器就是显示不出来。找了很多原因&#xff0c;最后有个老师和我说是内核版本的…

DBMS-基本概念

文件处理系统&#xff08;file-processing system&#xff09;的主要弊端&#xff1a; 数据冗余和不一致&#xff08;data redundancy and inconsistency&#xff09;、数据访问困难&#xff08;difficulty in accessing data&#xff09;、数据孤立&#xff08;data isolation…

python多大孩子可以学_孩子学编程最佳年龄是多大

儿童编程教育已经悄悄地掀起了编程低龄化的热浪。但是很多人会疑惑&#xff0c;到底孩子学编程最佳年龄是多少呢&#xff1f;下面小编就为大家解答一下。孩子学编程最佳年龄 首先&#xff0c;孩子的学习黄金时期是非常重要的。从6岁开始&#xff0c;大多数孩子都可以掌握对基本…

上传文件到华为云云服务器,上传文件到云服务器

上传文件到云服务器 内容精选换一换登录Windows操作系统的弹性云服务器时&#xff0c;需使用密码方式登录。因此&#xff0c;用户需先根据创建弹性云服务器时使用的密钥文件&#xff0c;获取该弹性云服务器初始安装时系统生成的管理员密码(Administrator帐户或Cloudbase-init设…

JUnit规则

第一次偶然发现JUnit Rule批注时&#xff0c;我对此概念有些恼火。 在测试用例中拥有一个公共领域似乎有些奇怪&#xff0c;因此我不愿意定期使用它。 但是一段时间后&#xff0c;我习惯了这一点&#xff0c;事实证明&#xff0c;规则可以通过多种方式简化编写测试的过程。 这篇…

微pe工具箱是微软的吗_微PE工具箱V2.0更新10内核

本帖最后由 韦小宝2 于 2017-3-22 21:26 编辑微PE工具箱V2.0发布更新了&#xff0c;链接&#xff1a;http://pan.baidu.com/s/1c9whpO 转载自无忧论坛 07年&#xff0c;第一个XP内核通用PE工具箱发布。17年&#xff0c;第一个WIN10内核的微PE工具箱就此诞生。64位纯内核&#x…

jq实现轮播图

之前设计了一个校团委网站&#xff0c;里面有一个轮播图效果&#xff0c;上网后查看了许多方法&#xff0c;觉得下面这个方法最为适用&#xff0c;记录下来 js代码&#xff1a; $(document).ready(function () {//无缝切换轮播var i 0;//索引var clone $(".banner .imgL…

关于图片预加载的思考

引子&#xff1a; 很多时候&#xff0c;我们在写html页面的时候&#xff0c;当需要在页面中加入图片时&#xff0c;我们很自然地把图片直接用<img>标签放在了<body>里面&#xff0c;这本来是没有多大问题的。 但是当图片数量很多的时候&#xff0c;问题就来了。H…

oracle安装中桌面模式与服务器模式的去别

桌面模式只能本机使用。 服务器模式可以在网络中使用&#xff0c;也就是网络中的其他服务器可以使用。 所以安装时&#xff0c;如果是生产环境肯定是服务器模式。一般也都是服务器模式。 转载于:https://www.cnblogs.com/zhjx0521/p/7803691.html

python不能创建字典的是_用Python创建带有重复键的字典

用Python创建带有重复键的字典 我有以下列表&#xff0c;其中包含重复的具有不同值的汽车注册号。 我想将其转换为字典&#xff0c;该字典接受汽车登记号的多个键。 到目前为止&#xff0c;当我尝试将列表转换为字典时&#xff0c;它消除了键之一。 如何制作具有重复键的字典&a…

python中int是什么的缩写_python中int是什么类型

python中的基本数据类型1:虽然python中的变量不需要声明&#xff0c;但使用时必须赋值整形变量浮点型变量字符型2:可以一个给多个变量赋值&#xff0c;也可以多个给多个变量赋值3:python3中有6个标准数据类型Number(数字)*True1*False0*数值的除法(/)总是返回一个浮点数&#x…

redis cli命令

redis安装后&#xff0c;在src和/usr/local/bin下有几个以redis开头的可执行文件&#xff0c;称为redis shell&#xff0c;这些可执行文件可做很多事情。 可执行文件作用redis-server 启动redisredis-cliredis命令行工具redis-benchmark基准测试工具redis-check-aofAOF持久化文…

高级ZK:异步UI更新和后台处理–第2部分

介绍 在第1部分中&#xff0c;我展示了如何在ZK应用程序中使用服务器推送和线程来执行后台任务。 但是&#xff0c;这个简单的示例具有一个重大缺陷&#xff0c;这使其对于实际应用程序而言是一种不好的方法&#xff1a;它为每个后台任务启动了一个新线程。 JDK5引入了Execut…

css清除浮动的原理

最近学习css发现了高度塌陷时候要清除浮动,为了理解清楚浮动原理,网上找了不少资料,发现都写的不是很清楚,而且都是一模一样的内容,我在里分享一下我对清楚浮动原理的理解, 如果你已经很了解什么是浮动和浮动的效果你可以直接跳转到三.如何清除浮动(重点)阅读 一.什么是浮动首…

SpringBoot03 项目热部署

1 问题 在编写springBoot项目时&#xff0c;经常需要修改代码&#xff1b;但是每次修改代码后都需重新启动&#xff0c;修改的代码才会生效 2 这么实现IDEA能够像Eclipse那样保存过后就可以自动进行刷新呢 将springBoot项目进行热部署即可 3 如何实现SpringBoot项目的热部署01 …

STM32实现流水灯

led.c #include"led.h"void Led_Init(void) {GPIO_InitTypeDef GPIO_VALUE; //???RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//???GPIO_VALUE.GPIO_ModeGPIO_Mode_Out_PP;//???? ????GPIO_VALUE.GPIO_PinGPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_…

jacob 报错 Can't co-create object

问题&#xff1a;开始时一切正常&#xff0c;后来什么都没该&#xff0c;出现Cant co-create object报错&#xff0c;即是创建不了ActiveXComponent wdnew ActiveXComponent("Word.Application"); 偶尔发现任务管理器中word进程居然达到10个&#xff0c;而我没有打开…

map分组后取前10个_map根据属性排序、取出map前n个

/*** map根据value排序* flag 1 正序* flag 0 倒序** param map* param flag* return*/public static > LinkedHashMap sortByValue(Map map, int flag) {LinkedHashMap sortMap new LinkedHashMap<>();if (flag 1) {map.entrySet().stream().sorted(Comparator.c…

wxpython可视化_使用wxPython的绘图模块wxPyPlot进行数据可视化

[Python进阶(四十)-数据可视化の使用matplotlib进行绘图前言  matplotlib是基于Python语言的开源项目&#xff0c;旨在为Python提供一个数据绘图包。我将在这篇文章中介绍matplotlib A #-*- coding: utf-8 -*- ############################################################…

在Java EE 6中将Bean验证与JAX-RS集成

JavaBeans验证&#xff08;Bean验证&#xff09;是一种新的验证模型&#xff0c;可作为Java EE 6平台的一部分使用。 约束条件支持Bean验证模型&#xff0c;该约束以注释的形式出现在JavaBeans组件&#xff08;例如托管Bean&#xff09;的字段&#xff0c;方法或类上。 javax.…