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.pswp.cn/news/370681.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370681.shtml
英文地址,請注明出處:http://en.pswp.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.…