本文為原創(chuàng)文章幔欧,轉(zhuǎn)載請注明出處罪治,謝謝你……
> 喜歡java并發(fā)編程的請加群:736156823
開始-->
很喜歡使用volatile關(guān)鍵字,還沒有啥需要特殊關(guān)注的礁蔗,平時用的也很嗨觉义,但是最近通過反射修改了這個字段,發(fā)現(xiàn)了一些小問題浴井,描述如下:
1.
這個字段在初始化時候由spring加載時候讀取配置文件中的值通過反射設(shè)置進來晒骇,代碼如下:
反射替換好后,打印結(jié)果:
這時直接打印是沒有問題的,與properties文件中的值保持一致洪囤,立刻可見徒坡。這是由spring啟動線程打印的。(代碼最好不要掛火車瘤缩,哈哈……)
2.所有初始化完畢后喇完,會通過信號量的機制,提醒另一個線程打印結(jié)果剥啤,代碼如下:
負(fù)責(zé)打印的另一個線程代碼如下:
3.問題來了:
spring線程打印的結(jié)果是配置文件的值锦溪,但是打印線程的打印結(jié)果卻是代碼中的默認(rèn)值……怪了……哈哈
下面本人解決辦法與問題猜測(很不專業(yè),哈哈……)铐殃。
解決:
這個方法簡單好用(不好用)海洼。
就剛才,我測試了下富腊,剛開始使用lock還好使的』捣辏現(xiàn)在竟然不好使了,哈哈……好奇妙赘被,如下圖:
配置文件中配置的值是on是整,但是使用lock打印的結(jié)果卻是off……哈哈,奇妙……
再啟動的時候先通過spring反射修改掉民假,在spring中打印config類中的值是on浮入,但是全部啟動完后,通過信號量使用打印線程打印出的竟然是off羊异,打印方法是帶有l(wèi)ock的事秀,這兩部之間沒有任何其余修改動作。
更奇妙的又來了野舶,哈哈……
系統(tǒng)中有許多定時任務(wù)易迹,任務(wù)中需要獲得開關(guān)的值,但是平道,這些獲取值的動作獲取到的值竟然是全部正確的睹欲,哈哈……厲害……
針對以上情況改動如下。
因為定時任務(wù)啟動有延遲一屋,那么我直接修改延遲時間為0窘疮,測試下:
出現(xiàn)兩個問題,配置文件中button全部是on冀墨,代碼中button全部是off闸衫,第一個截圖中既有on又有off,這個打印實在一個lock中的诽嘉;第二楚堤,在定時器立即啟動運行時原來打印為off的全部是on了疫蔓,而且之后的全部值都是on含懊。
小完結(jié):
1.說下本人對volatile關(guān)鍵字的理解吧身冬,哎……
添加緩存行失效標(biāo)記……每次讀取內(nèi)存中的值,不使用線程本地緩存……每次修改完成會強制刷新回主存岔乔,那么誰來幫助刷新(這是我一直關(guān)注的問題)酥筝?操作系統(tǒng)總線機制幫忙刷新,至于什么時候刷新雏门,刷新速度嘿歌,每次刷新允許最小間隔是多少,不得而知茁影,可以參考《計算機組成原理》宙帝,不同平臺略有區(qū)別,況且jvm內(nèi)存模型是怎么配合操作系統(tǒng)的我也不清楚募闲。所以本人使用時候還沒遇到過什么問題步脓,只要知道哪里是關(guān)鍵就好了,其他的不要多想浩螺。
這次系統(tǒng)中需要一個功能就是對配置文件的熱加載能夠及時的反應(yīng)到定時任務(wù)中靴患,并且能夠根據(jù)變換,立即修改定時間隔要出,重新啟動定時鸳君,所以才有上面的問題出現(xiàn)。
2.正因為上面volatile關(guān)鍵字的特點所以才有上述的奇妙患蹂,但是本人的系統(tǒng)是異步的或颊,不允許有阻塞或者說長時間阻塞,所以我在這里传于,僅僅是為了初始化時候打印正常囱挑,加了一短促等待:
至于對功能上的影響,還是比較少的格了,畢竟:1.定時延遲大于1秒看铆;2.系統(tǒng)總線刷新緩存很快。所以盛末,沒有影響弹惦。
3.上述打印的地方仍然是使用lock的,現(xiàn)在不修改了悄但。
4.關(guān)于打印方法:
由于打印方法是異步調(diào)用棠隐,初始化線程是通過信號量觸發(fā)其他線程打印的,所以都不會有阻塞檐嚣,都是正常的執(zhí)行過程助泽,所以暫時都這樣來修改了啰扛。
5.由于是熱加載的,即時生效嗡贺,所以我剛才修改了下配置文件隐解,然后文件監(jiān)控器通過信號量喚醒觸發(fā),結(jié)果如下:
看吧诫睬,系統(tǒng)刷新還是很快的煞茫,哈哈……
6.所以,這樣一來摄凡,沒有理解volatile的朋友是不是理解了续徽,所以,這個用起來還是不錯的亲澡,畢竟操作系統(tǒng)還是可以的钦扭,哈哈……至于指令重排,對象的完整初始化保證等能力床绪,大家還是自行百度吧
8.后續(xù)跟進seda模型
> 喜歡java并發(fā)編程的請加群:736156823
結(jié)束-->
本文為原創(chuàng)文章,轉(zhuǎn)載請注明出處会涎,謝謝你……