![Java并發(fā)編程_第1頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/16/1729192f-4d33-4a08-a09d-e75b2642a0ef/1729192f-4d33-4a08-a09d-e75b2642a0ef1.gif)
![Java并發(fā)編程_第2頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/16/1729192f-4d33-4a08-a09d-e75b2642a0ef/1729192f-4d33-4a08-a09d-e75b2642a0ef2.gif)
![Java并發(fā)編程_第3頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/16/1729192f-4d33-4a08-a09d-e75b2642a0ef/1729192f-4d33-4a08-a09d-e75b2642a0ef3.gif)
![Java并發(fā)編程_第4頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/16/1729192f-4d33-4a08-a09d-e75b2642a0ef/1729192f-4d33-4a08-a09d-e75b2642a0ef4.gif)
![Java并發(fā)編程_第5頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/16/1729192f-4d33-4a08-a09d-e75b2642a0ef/1729192f-4d33-4a08-a09d-e75b2642a0ef5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、Java并發(fā)編程:Volatile不能保證數(shù)據(jù)同步在本篇博文中,將給出一個實例去驗證volatile修飾的變量并不能保證其數(shù)據(jù)同步。在本篇博文中,將給出一個實例去驗證volatile修飾的變量并不能保證其數(shù)據(jù)同步。Java內(nèi)存模型規(guī)定了所有變量都存儲在主內(nèi)存中,每條線程都有自己的工作內(nèi)存,線程的工作內(nèi)存保存了被該線程使用到變量的主內(nèi)存副本拷貝,線程 對變量的所有操作(讀取,賦值等)都必須在工作內(nèi)存中進行,而不能直接讀寫主內(nèi)存中的變量。不同線程也不能直接訪問對方工作內(nèi)存中的變量,線程間變量值的 傳遞均需要通過主內(nèi)存來完成,線程,主內(nèi)存,工作內(nèi)存三者的交互關(guān)系如圖所示。當一個變量定義成volati
2、le之后, 保證了此變量對所有線程的可見性,也就是說當一條線程修改了這個變量的值,新的值對于其它線程來說是可以立即得知的.此時,該變量的讀寫操作直接在主內(nèi)存中完成.Volatile 變量具有 synchronized 的可見性特性,但是不具備原子特性。Volatile variables share the visibility features of synchronized, but none of the atomicity features.雖然增量操作(x+)看上去類似一個單獨操作,實際上它是一個由讀取修改寫入操作序列組成的組合操作,必須以原子方式執(zhí)行,而 volatile 不能提供
3、必須的原子特性。While the increment operation (x+) may look like a single operation, it is really a compound read-modify-write sequence of operations that must execute atomically - and volatile does not provide the necessary atomicity.在多線程并發(fā)的環(huán)境下, 各個線程的讀/寫操作可能有重疊現(xiàn)象, 在這個時候, volatile并不能保證數(shù)據(jù)同步.下面將給出一個實例:實例 =>
4、; 500個線程一起運行,每個線程對1到100求和1000次操作,然后將一個volatile共享變量值加1. 當500個線程都完成操作之后, 期望的值是500,因為每個線程執(zhí)行完畢之后都會對這個volatile變量加1.一直循環(huán)執(zhí)行這個程序,直到出現(xiàn)volatile變量的值小于500為止,也就是出現(xiàn)數(shù)據(jù)不同步。1. public class NonSafeThread implements Runnable 2. 3. /* 共享資源, 每個線程執(zhí)行完之
5、后加 1 */ 4. private volatile int volatileCount = 0; 5. 6. public void run() 7. 8. /* 9.
6、0; * 每個線程調(diào)用sum100()方法,1000次 10. */ 11. 12. for (int i = 1; i <= 1000; i+) 13.
7、0; sum100(); 14. 15. 16. /* 17. * 計算完畢之后, volatileCount 加 1 18
8、. */ 19. 20. increase(); 21. 22. 23. private void increase() 24.
9、 25. volatileCount+; 26. 27. 28. /* 29. * 對 1 到 100 求和 30. */ 31.
10、0; private int sum100() 32. int result = 0; 33. for (int i = 1; i <= 100; i+) 34.
11、0; result += i; 35. 36. return result; 37. 38. 39. /* 4
12、0. * return the volatileCount 41. */ 42. public int getVolatileCount() 43. return volatileCount; 44.
13、; 45. 46. 1. /* 2. * author Eric 3. * 4. * version 1.0 5. */ 6. 7. public class NonSafeThreadTest 8. 9. public static void m
14、ain(String args) 10. 11. /* 記錄循環(huán)次數(shù) */ 12. int loopCount = 0; 13. 14. /* 以main函數(shù)主線程創(chuàng)建一個是線
15、程組 */ 15. ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); 16. 17. for (;) 18. &
16、#160; loopCount+; 19. 20. /* 21. * 啟動500個線程,初始化的線程會添加到當前線程組中 22.
17、 */ 23. NonSafeThread nonSafeThread = new NonSafeThread(); 24. startThreads(nonSafeThread);
18、25. 26. /* 27. * 如果線程組中除了主線程之外,還有其它線程,則休眠5毫秒,然后再判斷線程組中 剩余的線程數(shù),直到只剩下主線程一個為止。 28.
19、160; */ 29. while (!isOnlyMainThreadLeft(threadGroup) 30. sleep(5); 31.
20、; 32. 33. /* 34. * 500個線程運行完畢,那么此時的volatile變量volatileCount的值應(yīng)該5
21、00, 因為每個線程將其值加1。 35. * 36. * 驗證是否出現(xiàn)線程不安全的情況。 37.
22、0; */ 38. validate(loopCount, nonSafeThread.getVolatileCount(), 500); 39. 40. 41. 42.
23、60;/* 43. * 啟動500個線程 44. */ 45. private static void startThreads(NonSafeThread nonSafeThread) 46. 47. for
24、(int i = 0; i < 500; i+) 48. new Thread(nonSafeThread).start(); 49. 50. 51. 52.
25、 /* 53. * 驗證是否出現(xiàn)線程不安全的情況。 如果是,則打印出線程不安全的信息。 54. */ 55. private static void validate(int loopCount, int actualValue, 56.
26、 int expectedValue) 57. if (!isVolatileCountExpected(actualValue, expectedValue) 58.
27、;printNonSafeMessage(loopCount, actualValue, expectedValue); 59. /* 60. * 正常退出程序。 61.
28、0; */ 62. System.exit(0); 63. 64. 65. 66. /* 67.
29、60; * 在控制臺打印出現(xiàn)線程不安全時的信息。 68. */ 69. private static void printNonSafeMessage(int loopCount, int actualValue, 70. &
30、#160;int expectedValue) 71. System.out.println(String.format( 72. "第%d次循環(huán),出現(xiàn)線程不安全的情況,volatile的值不正確,期望值是%d, 但是500個線程運行的情況下是%d&
31、quot;, 73. loopCount, expectedValue, actualValue); 74. 75. 76. /* 77. * 判斷實際中的volati
32、le值與期望值是否一致。 78. */ 79. private static boolean isVolatileCountExpected(int actualValue, 80. int expectedValue) 81.
33、160; return actualValue = expectedValue; 82. 83. 84. /* 85. * 讓線程休眠millis毫秒 86. */ 87.
34、 private static void sleep(long millis) 88. try 89. Thread.sleep(millis); 90.
35、160;catch (InterruptedException e) 91. / TODO Auto-generated catch block 92. e.printStackTrace(); 93.
36、60; 94. 95. 96. /* 97. * 判斷一個線程組是否只剩下主線程了。 98. * 99. * 如果是則返回true,如果不是則放
37、回false. 100. */ 101. private static boolean isOnlyMainThreadLeft(ThreadGroup tg) 102. return tg.activeCount() = 1; 103.
38、; 104. 105. 某次運行,輸出的結(jié)果如下:第83次循環(huán),出現(xiàn)線程不安全的情況,volatile的值不正確,期望值是500, 但是500個線程運行的情況下是499在這種情況下,可以通過 Lcak和synchronized來保證數(shù)據(jù)的同步。如:1. 使用Lock,修改NonSafeThread類的run方法的內(nèi)容:1. public void run() 2. 3. lock.lock();
39、60;4. 5. try 6. /* 7. * 每個線程調(diào)用sum100()方法,1000次 8.
40、160; */ 9. 10. for (int i = 1; i <= 1000; i+) 11.
41、 sum100(); 12. 13. 14. /* 15.
42、60; * 計算完畢之后, volatileCount 加 1 16. */ 17. 18. increase(); 19.
43、; 20. finally 21. lock.unlock(); 22. 23. 24. 2. 使用synchronized 1. public void run() 2. &
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 七年級數(shù)學(xué)上冊第30課時銷售問題和儲蓄問題聽評課記錄新湘教版
- 湘教版數(shù)學(xué)八年級上冊《1.1 分式》聽評課記錄
- 人教版歷史七年級下冊第1課《隋朝的統(tǒng)一與滅亡》聽課評課記錄
- 2022年新課標八年級上冊道德與法治《7.1 關(guān)愛他人 》聽課評課記錄
- 生物技術(shù)創(chuàng)新合作開發(fā)合同(2篇)
- 理財委托合同(2篇)
- 人教版數(shù)學(xué)八年級下冊20.1.1《平均數(shù)》聽評課記錄3
- 語文聽評課記錄九年級
- 人教版數(shù)學(xué)八年級上冊《11.2.2三角形的外角》聽評課記錄1
- 數(shù)學(xué)七年級下學(xué)期《立方根》聽評課記錄
- 蘇州2025年江蘇蘇州太倉市高新區(qū)(科教新城婁東街道陸渡街道)招聘司法協(xié)理員(編外用工)10人筆試歷年參考題庫附帶答案詳解
- 搞笑小品劇本《大城小事》臺詞完整版
- 2025至2031年中國助眠床墊行業(yè)投資前景及策略咨詢研究報告
- 物業(yè)服務(wù)和后勤運輸保障服務(wù)總體服務(wù)方案
- 2025四川中煙招聘高頻重點提升(共500題)附帶答案詳解
- 2025年極兔速遞有限公司招聘筆試參考題庫含答案解析
- 2025年北京市文化和旅游局系統(tǒng)事業(yè)單位招聘101人筆試高頻重點提升(共500題)附帶答案詳解
- 2025年中儲棉總公司招聘筆試參考題庫含答案解析
- 2024-2030年中國科技孵化器產(chǎn)業(yè)發(fā)展現(xiàn)狀及投融資戰(zhàn)略分析報告
- 中學(xué)學(xué)校2024-2025學(xué)年第二學(xué)期教學(xué)工作計劃
- 人大代表小組活動計劃人大代表活動方案
評論
0/150
提交評論