標籤:java
轉載請註明出處http://blog.csdn.net/xingjiarong/article/details/47603813
什麼是Race Condition
首先,什麼是Race Condition呢,Race Condition中文翻譯是競爭條件,是指多個進程或者線程並發訪問和操作同一資料且執行結果與訪問發生的特定順序有關的現象。換句話說,就是線程或進程之間訪問資料的先後順序決定了資料修改的結果,這種現象在多線程編程中是經常見到的。
Race Condition 執行個體
class MyThread implements Runnable { /** * 計算類型,1表示減法,其他的表示加法 */ private int type; public MyThread(int type) { this.type = type; } public void run() { if (type == 1) for (int i = 0; i < 10000; i++) Test.num--; else for (int i = 0; i < 10000; i++) Test.num--; }}public class Test { public static int num = 1000000; public static void main(String[] args) { Thread a = new Thread(new MyThread(1)); Thread b = new Thread(new MyThread(2)); a.start(); b.start(); /* * 主線程等待子線程完成,然後再列印數值 */ try { a.join(); b.join(); } catch (Exception e) { e.printStackTrace(); } System.out.println(num); }}
上邊的程式非常簡單。就是用兩個線程同時操作和修改同一個資料,一個線程希望把num加10000,另一個線程希望把num減小10000,根據我們的計算,一個數加上10000,再減去10000,相當於沒有變化,所以結果應該等於他自身。但是這隻是我們的想象,事實真的是這樣嗎?大家可以運行一下上邊的程式,你會吃驚的發現,結果並不是1000000,再多運行幾次,是不是每次的結果都不一樣。
沒錯,這就是產生了Race Condition,有兩個線程,同時操作num這個變數,並且操作的結果與訪問的順序有關(這個不是我們控制的,而是由作業系統控制的,我們只能看到每次的結果都不一樣)。
Race Condition 產生的原因
現在我們已經看到了Race Condition現象了,那麼它是怎麼產生的呢?先不要急切的說,你不是說了嗎,是由於訪問順序不同造成的。我想說,學習新知識一定要追根溯源,要真正的弄明白,那麼在硬體或者作業系統層面上,這一現象發生的原因是什麼呢?
首先,我們來看一張圖。
我們知道,在作業系統中,作業系統程式為每個線程分配了單獨的寄存器和程式計數器。在上邊的圖中,我一共分成了三列,其中第一列表示線程一的操作過程,第二列表示線程二的操作過程,第三列表示記憶體中的結果。圖中前兩列的寫著數位小方框表示該線程所使用的寄存器,數字表示該寄存器中的值。第三列的小方框表示記憶體中的 一個儲存單元,數值表示記憶體中儲存的數值。
現在,我們來看一下操作的過程。(這裡是簡化了的示意過程,真正的過程要複雜的多)開始時,資料都是放在記憶體中的,所以通過LOAD指令,將num載入到寄存器中,接著執行相應的操作指令,這裡分別為ADD(加1) SUB(減1)指令,指令執行結束後,結果是儲存在相應的寄存器中的,這時記憶體中的數值還沒有發生變化。最後執行STORE指令之後,寄存器中的數值被儲存到記憶體中。
小方框從上到下的順序表示線程1和線程2交替執行的過程。首先,線程1讀取了記憶體中num的值,然後換到線程2執行,先讀取了記憶體中num的數值,然後執行減1操作,最後將結果寫回記憶體中,這時記憶體中的資料變成了999999,但是這一個變化線程1是看不到的,因為這一變化發生線上程1讀取num的值之後。其實這時線程1讀取到的資料已經是不正確的資料了,這是產生Race Condition的根本原因。然後線程1接著執行未執行完的指令,加1操作,最後將1000001寫會記憶體,這是產生Race Condition的直接原因,它將線程2的結果給覆蓋掉了。
這就是Race Condition產生的原因,大家是不是真正的明白了呢?。
當然Race Condition這種現象是不好的,所以我們會通過各種途徑來避免產生Race Condition。在接下來的部落格裡,我會為大家介紹如果在java的多線程編程中避免出現Race Condition 以及多線程的同步和互斥的內容,希望與大家一起學習一起進步,請大家繼續關注我的部落格,如果大家支援我的話,就頂我一下吧。
著作權聲明:本文為博主原創文章,轉載請註明出處,查看原文章,請訪問:http://blog.csdn.net/xingjiarong
java多線程(一)Race Condition現象及產生的原因