精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

JDK的一個Bug,監聽文件變更要小心了

開發 前端
本文實踐了一個很常見的功能,起初采用很符合常規思路的方案來解決,結果恰好碰到了JDK的Bug,只好變更策略來實現。

背景

在某些業務場景下,我們需要自己實現文件內容變更監聽的功能,比如:監聽某個文件是否發生變更,當變更時重新加載文件的內容。

看似比較簡單的一個功能,但如果在某些JDK版本下,可能會出現意想不到的Bug。

本篇文章就帶大家簡單實現一個對應的功能,并分析一下對應的Bug和優缺點。

初步實現思路

監聽文件變動并讀取文件,簡單的思路如下:

  • 單起一個線程,定時獲取文件最后更新的時間戳(單位:毫秒);
  • 對比上一次的時間戳,如果不一致,則說明文件被改動,則重新進行加載;

這里寫一個簡單功能實現(不包含定時任務部分)的demo:

public class FileWatchDemo {

/**
* 上次更新時間
*/
public static long LAST_TIME = 0L;

public static void main(String[] args) throws IOException {

String fileName = "/Users/zzs/temp/1.txt";
// 創建文件,僅為實例,實踐中由其他程序觸發文件的變更
createFile(fileName);

// 執行2次
for (int i = 0; i < 2; i++) {
long timestamp = readLastModified(fileName);
if (timestamp != LAST_TIME) {
System.out.println("文件已被更新:" + timestamp);
LAST_TIME = timestamp;
// 重新加載,文件內容
} else {
System.out.println("文件未更新");
}
}
}

public static void createFile(String fileName) throws IOException {
File file = new File(fileName);
if (!file.exists()) {
boolean result = file.createNewFile();
System.out.println("創建文件:" + result);
}
}

public static long readLastModified(String fileName) {
File file = new File(fileName);
return file.lastModified();
}
}

在上述代碼中,先創建一個文件(方便測試),然后兩次讀取文件的修改時間,并用LAST_TIME記錄上次修改時間。如果文件的最新更改時間與上一次不一致,則更新修改時間,并進行業務處理。

示例代碼中for循環兩次,便是為了演示變更與不變更的兩種情況。執行程序,打印日志如下:

文件已被更新:1653557504000
文件未更新

執行結果符合預期。

這種解決方案很明顯有兩個缺點:

  • 無法實時感知文件的變動,程序輪訓畢竟有一個時間差;
  • lastModified返回的時間單位是毫秒,如果同一毫秒內容出現兩次改動,而定時任務查詢時恰好落在兩次變動之間,則后一次變動則無法被感知到。

第一個缺點,對業務的影響不大;第二個缺點的概率比較小,可以忽略不計;

JDK的Bug登場

上面的代碼實現,正常情況下是沒什么問題的,但如果你使用的Java版本為8或9時,則可能出現意想不到的Bug,這是由JDK本身的Bug導致的。

編號為JDK-8177809的Bug是這樣描述的:

Bug地址為:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8177809

這個Bug的基本描述就是:在Java8和9的某些版本下,lastModified方法返回時間戳并不是毫秒,而是秒,也就是說返回結果的后三位始終為0。

我們來寫一個程序驗證一下:

public class FileReadDemo {

public static void main(String[] args) throws IOException, InterruptedException {

String fileName = "/Users/zzs/temp/1.txt";
// 創建文件
createFile(fileName);

for (int i = 0; i < 10; i++) {
// 向文件內寫入數據
writeToFile(fileName);
// 讀取文件修改時間
long timestamp = readLastModified(fileName);
System.out.println("文件修改時間:" + timestamp);
// 睡眠100ms
Thread.sleep(100);
}
}

public static void createFile(String fileName) throws IOException {
File file = new File(fileName);
if (!file.exists()) {
boolean result = file.createNewFile();
System.out.println("創建文件:" + result);
}
}

public static void writeToFile(String fileName) throws IOException {
FileWriter fileWriter = new FileWriter(fileName);
// 寫入隨機數字
fileWriter.write(new Random(1000).nextInt());
fileWriter.close();
}

public static long readLastModified(String fileName) {
File file = new File(fileName);
return file.lastModified();
}
}

在上述代碼中,先創建一個文件,然后在for循環中不停的向文件寫入內容,并讀取修改時間。每次操作睡眠100ms。這樣,同一秒就可以多次寫文件和讀修改時間。

執行結果如下:

文件修改時間:1653558619000
文件修改時間:1653558619000
文件修改時間:1653558619000
文件修改時間:1653558619000
文件修改時間:1653558619000
文件修改時間:1653558619000
文件修改時間:1653558620000
文件修改時間:1653558620000
文件修改時間:1653558620000
文件修改時間:1653558620000

修改了10次文件的內容,只感知到了2次。JDK的這個bug讓這種實現方式的第2個缺點無限放大了,同一秒發生變更的概率可比同一毫秒發生的概率要大太多了。

PS:在官方Bug描述中提到可以通過Files.getLastModifiedTime來實現獲取時間戳,但筆者驗證的結果是依舊無效,可能不同版本有不同的表現吧。

更新解決方案

Java 8目前是主流版本,不可能因為JDK的該bug就換JDK吧。所以,我們要通過其他方式來實現這個業務功能,那就是新增一個用來記錄文件版本(version)的文件(或其他存儲方式)。這個version的值,可在寫文件時按照遞增生成版本號,也可以通過對文件的內容做MD5計算獲得。

如果能保證版本順序生成,使用時只需讀取版本文件中的值進行比對即可,如果變更則重新加載,如果未變更則不做處理。

如果使用MD5的形式,則需考慮MD5算法的性能,以及MD5結果的碰撞(概率很小,可以忽略)。

下面以版本的形式來展示一下demo:

public class FileReadVersionDemo {

public static int version = 0;

public static void main(String[] args) throws IOException, InterruptedException {

String fileName = "/Users/zzs/temp/1.txt";
String versionName = "/Users/zzs/temp/version.txt";
// 創建文件
createFile(fileName);
createFile(versionName);

for (int i = 1; i < 10; i++) {
// 向文件內寫入數據
writeToFile(fileName);
// 同時寫入版本
writeToFile(versionName, i);
// 監聽器讀取文件版本
int fileVersion = Integer.parseInt(readOneLineFromFile(versionName));
if (version == fileVersion) {
System.out.println("版本未變更");
} else {
System.out.println("版本已變化,進行業務處理");
}
// 睡眠100ms
Thread.sleep(100);
}
}

public static void createFile(String fileName) throws IOException {
File file = new File(fileName);
if (!file.exists()) {
boolean result = file.createNewFile();
System.out.println("創建文件:" + result);
}
}

public static void writeToFile(String fileName) throws IOException {
writeToFile(fileName, new Random(1000).nextInt());
}

public static void writeToFile(String fileName, int version) throws IOException {
FileWriter fileWriter = new FileWriter(fileName);
fileWriter.write(version +"");
fileWriter.close();
}

public static String readOneLineFromFile(String fileName) {
File file = new File(fileName);
String tempString = null;
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
//一次讀一行,讀入null時文件結束
tempString = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return tempString;
}
}

執行上述代碼,打印日志如下:

版本已變化,進行業務處理
版本已變化,進行業務處理
版本已變化,進行業務處理
版本已變化,進行業務處理
版本已變化,進行業務處理
版本已變化,進行業務處理
版本已變化,進行業務處理
版本已變化,進行業務處理
版本已變化,進行業務處理

可以看到,每次文件變更都能夠感知到。當然,上述代碼只是示例,在使用的過程中還是需要更多地完善邏輯。

小結

本文實踐了一個很常見的功能,起初采用很符合常規思路的方案來解決,結果恰好碰到了JDK的Bug,只好變更策略來實現。當然,如果業務環境中已經存在了一些基礎的中間件還有更多解決方案。

而通過本篇文章我們學到了JDK Bug導致的連鎖反應,同時也見證了:實踐見真知。很多技術方案是否可行,還是需要經得起實踐的考驗才行。趕快檢查一下你的代碼實現,是否命中該Bug?

責任編輯:武曉燕 來源: 程序新視界
相關推薦

2022-05-16 08:42:26

Pandasbug

2021-09-13 08:41:52

職場互聯網自閉

2020-01-10 09:20:03

手機ISOJDK

2018-06-20 15:50:38

JDK9JVMJDK10

2020-09-29 07:44:20

跨域前后端分離插件

2009-09-14 17:08:02

WebFormView

2025-02-13 07:00:00

Dubbo-goJava服務端

2021-04-22 07:47:47

JavaJDKMYSQL

2022-11-30 09:18:51

JavaMyBatisMQ

2022-05-10 12:20:04

JDKversion故障

2021-10-08 07:50:57

軟件設計程序

2011-07-29 16:55:44

Java 7

2017-10-10 15:14:23

BUGiOS 11蘋果

2015-01-23 10:04:56

bug程序員

2016-09-28 14:00:56

2023-01-26 11:43:03

線程池CPUJava

2024-10-25 12:38:27

2023-06-20 08:25:53

NESTED源碼mybatis

2014-12-17 09:40:22

dockerLinuxPaaS

2024-04-22 00:00:01

Redis集群
點贊
收藏

51CTO技術棧公眾號

亚洲欧洲美洲综合色网| 成年人小视频在线观看| 国产熟妇搡bbbb搡bbbb| 麻豆视频在线观看免费| 六月丁香久久丫| 日韩美女精品在线| 成人综合电影| 男操女免费网站| 无码国产精品高潮久久99| 亚洲情侣在线| 欧美三级资源在线| 日韩av一区二区三区美女毛片| 欧美久久久久久久久久久久| 少妇高潮一区二区三区99| 国产亚洲一本大道中文在线| 国外成人性视频| 性高潮久久久久久| 国产成人l区| 免费在线观看视频一区| 亚洲欧美日韩精品| 免费日韩视频在线观看| 五月天婷婷在线观看| 热久久久久久久| 一区二区三区回区在观看免费视频| 成人性生活视频免费看| 粉嫩av一区二区夜夜嗨| 一区二区不卡| 亚洲欧美自拍一区| 天堂…中文在线最新版在线| 欧洲精品久久一区二区| 国产精品va| 亚洲精品在线三区| 狠狠干 狠狠操| 久操视频在线免费播放| 精品在线播放免费| 久久色免费在线视频| 性久久久久久久久久久久久久| 久久国产精品一区| 久久精品日韩一区二区三区| 国产伦精品一区二区三区高清版| 国产无码精品视频| 欧美巨大xxxx| 色美美综合视频| 中文字幕色一区二区| 国产免费黄色大片| 国产一区二区三区四区三区四 | 国产另类在线| 亚洲高清在线视频| 国产日韩欧美精品| 黄瓜视频在线免费观看| 精品freesex老太交| 欧美日本视频在线| 香港三级日本三级a视频| 色婷婷在线视频| 日韩经典一区二区| 久久精品久久精品亚洲人| 黄色片免费网址| 日韩大陆av| 欧美人伦禁忌dvd放荡欲情| 日本久久久久久久久久久久| 91成人抖音| 一区二区三区 在线观看视频| 国产成人精品福利一区二区三区| 国产美女三级无套内谢| 国内精品久久久久影院薰衣草| 久久久久国产视频| 天堂网av2018| 欧美人与动xxxxz0oz| 亚洲国产另类久久精品| 奇米影视四色在线| 涩涩网在线视频| 亚洲欧美在线视频观看| 资源网第一页久久久| 久草中文在线| 亚洲一区自拍偷拍| 神马影院午夜我不卡| 亚洲国产av一区二区| 日韩av午夜在线观看| 国产精品igao视频| 在线看成人av| 97在线精品| 亚洲欧美日韩精品| 自拍偷拍第9页| 九一成人免费视频| 精品久久久久久久久久久久久久久久久| 日韩精品免费播放| 99thz桃花论族在线播放| 国产精品高潮久久久久无| 精品国产免费久久久久久尖叫 | 欧美黄片一区二区三区| 精品国产一区二区三区噜噜噜 | 日韩高清在线观看| 成人a级免费视频| 日韩欧美中文字幕一区二区| 中文av一区| 91精品国产99| 国产真实的和子乱拍在线观看| 国产精品亚洲综合色区韩国| 欧美夫妻性生活xx| 娇妻被老王脔到高潮失禁视频| 成人看片爽爽爽| 日韩一区二区精品| 日韩在线一区视频| 国产精品美女午夜爽爽| 91福利在线导航| 欧美性受xxxx黒人xyx性爽| 麻豆成人入口| 日韩一区二区久久久| 一级黄色片网址| 欧美视频福利| 九九热这里只有精品6| 自拍偷拍第9页| 亚洲精品欧洲| 97视频免费观看| 日韩高清精品免费观看| 美女在线观看视频一区二区| 国产精品一区二区欧美| 日本视频在线播放| 亚洲人成人一区二区在线观看| 中文字幕欧美人与畜| av在线私库| 欧美一区二区三区的| 中文字幕55页| 粉嫩一区二区三区四区公司1| 亚洲最新av网址| 日本道在线观看| 久久久久久网| 国产精品自产拍高潮在线观看| 伊人网综合在线| 韩国欧美国产1区| 日本一区视频在线播放| 僵尸再翻生在线观看| 五月天丁香久久| 99免费视频观看| 一区二区三区四区精品视频| 亚洲国内精品视频| 18岁成人毛片| 日韩午夜免费视频| 国产精品成人免费视频| 99国产精品一区二区三区| 国产欧美一区二区精品秋霞影院| 亚洲一区二区四区| 欧美videosex性极品hd| 欧美日韩另类在线| 三级在线免费看| 亚洲国产高清在线观看| 亚洲美女av在线| 黄色片免费观看视频| 国产99久久久国产精品潘金网站| 国产在线观看精品| 91超薄丝袜肉丝一区二区| 福利一区福利二区| 中文字幕一区二区三区在线乱码| 精品国模一区二区三区| 欧美精品成人一区二区三区四区| 91免费视频污| 国产精品久久久久9999赢消| 欧美夫妻性生活视频| 97人妻精品一区二区三区软件 | 久久6免费视频| 欧美日韩国产一区二区三区不卡| 欧美在线性爱视频| 无码人妻精品一区二区50| 奇米777欧美一区二区| 日韩精品av一区二区三区| 亚洲国产福利| 欧美视频在线观看一区二区| 奇米777在线| 日韩免费特黄一二三区| 久久久久久久久久久免费| 国产特级黄色片| 国产欧美视频一区二区三区| 日日碰狠狠躁久久躁婷婷| 草莓视频成人appios| 欧美日韩成人在线一区| 正在播放国产对白害羞| 麻豆一区二区在线| 久久草视频在线看| 精品视频一二三| 亚洲一区在线观看免费观看电影高清| 中文字幕亚洲影院| 精品成人久久| 国产精品黄色av| 亚洲搞黄视频| 精品剧情v国产在线观看在线| 国产一级做a爰片在线看免费| www.日韩av| 日韩免费中文专区| 国产精品久久国产精麻豆96堂| 亚洲一区欧美二区| 中文字幕精品—区二区| 国产一二三区精品| 国内精品伊人久久久久影院对白| 亚洲国产精品一区在线观看不卡 | 日韩黄色中文字幕| 91av精品| 欧美一级免费视频| 国产精品无码免费播放 | 国产精品9999久久久久仙踪林| h片在线观看下载| 亚洲欧洲一区二区三区在线观看| 日本妇乱大交xxxxx| 一区二区三区精品视频在线| 艳妇乳肉豪妇荡乳xxx| 国产一区二区三区四区五区传媒| zzijzzij亚洲日本成熟少妇| 午夜精品久久久久久久91蜜桃| 久久婷婷色综合| 久久精品国产精品亚洲精品色| 伊人久久综合一区二区| 中文字幕日韩电影| 好吊色一区二区| 欧美性色黄大片| 国产又爽又黄的视频| 国产精品福利一区| 欧类av怡春院| 午夜在线播放视频欧美| 日本中文字幕一级片| 91精品国产色综合久久不卡粉嫩| 亚洲小视频在线| 日韩欧美亚洲国产| aaa亚洲精品一二三区| 亚洲综合伊人久久| 三级精品在线观看| 久久综合久久网| 亚洲精品成人无限看| 先锋影音一区二区三区| 九九热播视频在线精品6| 成人精品一区二区三区电影免费 | 国产精品偷伦免费视频观看的| 黄网av在线| 91精品啪在线观看国产60岁| 日韩 欧美 中文| 亚洲一区二区欧美激情| 女教师淫辱の教室蜜臀av软件| 91亚洲国产成人精品一区二三| 视色,视色影院,视色影库,视色网| 欧美大片网站| 91精品国产高清久久久久久久久| 成人黄色网址| 日韩最新中文字幕电影免费看| 欧洲免费在线视频| 日韩欧美一区二区三区| 欧美黄色一级生活片| 一区二区日本视频| 在线观看成人免费| 99久久99视频只有精品| 手机成人在线| 日韩大片在线播放| 日本在线视频一区| 久久99国产精品视频| 久久久99国产精品免费| 在线日韩网站| 国产精品一区二区3区| 美女日韩欧美| 欧美综合国产精品久久丁香| 午夜伦理大片视频在线观看| 亚洲精品视频免费在线观看| 成人午夜精品视频| 欧美日韩一区免费| 国产成人愉拍精品久久| 天天色综合天天| 激情五月色婷婷| 图片区日韩欧美亚洲| 免费日韩一级片| 亚洲电影在线播放| 男人天堂2024| 欧美网站大全在线观看| 中文天堂在线资源| 天天色图综合网| 波多野结衣影片| 欧美中文字幕一区二区三区| 狂野欧美性猛交| 欧美国产1区2区| 初高中福利视频网站| 国产精品一区二区黑丝| 国产精品视频一区二区三区四区五区| 伊人成人在线视频| 全黄性性激高免费视频| 亚洲中字黄色| 在线观看免费成人av| 国产精品亚洲产品| 57pao国产成永久免费视频| 国产一区二区在线免费观看| 欧美一级片在线免费观看| 91免费观看视频在线| 中字幕一区二区三区乱码| 国产精品激情偷乱一区二区∴| 国产又黄又爽又无遮挡| 黑人巨大精品欧美一区免费视频| 日韩精品一区二区亚洲av| 在线观看成人免费视频| 国产精品一级视频| 亚洲免费高清视频| 毛片激情在线观看| 欧美精品xxx| 日韩在线免费| 国产精品av一区| 精品国产视频| 黄色一级片在线看| 免费欧美在线| 特种兵之深入敌后| 久久久亚洲欧洲日产国码αv| 日本黄色片免费观看| 欧美日韩黄色大片| 国产又粗又黄视频| 日韩国产欧美精品一区二区三区| 米奇精品一区二区三区| 91国产美女视频| 成人永久在线| 麻豆视频成人| 免费福利视频一区| 亚洲春色在线视频| 在线精品一区二区| 日日干夜夜操s8| 久久久亚洲欧洲日产国码αv| 国产黄色小视频网站| 欧美日韩国产丝袜另类| 精品人妻一区二区三区换脸明星 | 精品久久久久中文字幕小说 | 成人精品视频在线| 夜色77av精品影院| 九色自拍视频在线观看| 精一区二区三区| av网站免费在线播放| 亚洲国产aⅴ成人精品无吗| 国产三级自拍视频| 国产视频在线观看一区二区| 白浆在线视频| 99久久一区三区四区免费| 成人在线免费观看网站| 欧美日韩精品免费观看| 青青草原在线亚洲| 法国空姐在线观看免费| 蜜臀va亚洲va欧美va天堂| 亚洲av成人精品一区二区三区| 亚洲欧美日韩国产一区二区三区| youjizz在线视频| 亚洲精品美女在线| 国产在线88av| 超碰97人人在线| 亚洲成人二区| 亚洲色图偷拍视频| 欧美国产国产综合| 无码人妻精品一区二| 亚洲经典中文字幕| 欧美a级在线观看| 国产精品免费一区二区三区| 亚洲一区二区日韩| 五月六月丁香婷婷| 亚洲天堂2016| 国产精品国产精品国产专区| 一区二区三区四区精品| 69堂免费精品视频在线播放| 日本高清不卡一区二区三| 国产人成精品一区二区三| 中文字幕在线看高清电影| 久久女同精品一区二区| 日韩免费一级片| 亚洲精品一区二区三区精华液| 国产福利电影在线播放| 国模一区二区三区私拍视频| 亚洲精品视频啊美女在线直播| 污污免费在线观看| 亚洲免费成人在线视频| 免费观看30秒视频久久| 成人片黄网站色大片免费毛片| 亚洲动漫第一页| 性xxxx搡xxxxx搡欧美| 久久免费在线观看| 乱亲女h秽乱长久久久| 第四色婷婷基地| 翔田千里一区二区| 爱爱的免费视频| 欧美性大战久久久久久久| 国产精品一区二区三区四区色| 日韩av影视综合网| 九九热精品在线播放| 国产丝袜欧美中文另类| 欧美一区二区三区不卡视频| 永久免费看mv网站入口亚洲| 成人一区视频| 三年中文高清在线观看第6集| 国产乱色国产精品免费视频| 国产一级在线视频| 欧美性x x x| 亚洲一区二区视频在线观看| www.av在线.com| 性欧美长视频免费观看不卡| 成人黄色av网址| 日韩中文字幕免费在线| 国产精品美女久久久久久| www.色日本| 国产精品av在线播放| 亚洲电影在线一区二区三区| 日本wwwwwww| 欧美日韩精品福利| 蜜桃传媒在线观看免费进入 | 国产黑人绿帽在线第一区| 美女毛片一区二区三区四区最新中文字幕亚洲 |