首先要明白線程的工做原理,jvm有一個main memory,而每一個線程有本身的working memory,一個線程對一個variable進行操做時,都要在本身的working memory裏面創建一個copy,操做完以後再寫入main memory。多個線程同時操做同一個variable,就可能會出現不可預知的結果。根據上面的解釋,很容易想出相應的scenario。
而用synchronized的關鍵是創建一個monitor,這個monitor能夠是要修改的variable也能夠其餘你認爲合適的object好比method,而後經過給這個monitor加鎖來實現線程安全,每一個線程在得到這個鎖以後,要執行完 load到workingmemory -> use&assign -> store到mainmemory 的過程,纔會釋放它獲得的鎖。這樣就實現了所謂的線程安全。安全
------------------------------------------------------多線程
什麼是線程安全?線程安全是怎麼完成的(原理)?
線程安全就是說多線程訪問同一代碼,不會產生不肯定的結果。編寫線程安全的代碼是低依靠線程同步。jvm
------------------------------------------------------spa
在接口方式中,線程有一個共享的數據成員,即: private int count =10;
而在繼承方式中,線程之間沒有共享的成員,而是各線程各自有一個私有成員,即: private int count =10;
樓主的代碼恰好是一個好例子,說明了什麼時候須要考慮線程同步,並在必定程序上說明了怎樣才能編寫出線程安全的代碼。
在多線程環境中,當各線程不共享數據的時候,那麼必定是線程安全的。問題是這種狀況並很少見,在多數狀況下須要共享數據,這時就須要進行適當的同步控制了。線程
--------------------------------------------------------繼承
線程安全通常都涉及到synchronized 就是一段代碼同時只能有一個線程來操做 否則中間過程可能會產生不可預製的結果接口
---------------------------------------------------------進程
若是你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。若是每次運行結果和單線程運行的結果是同樣的,並且其餘的變量的值也和預期的是同樣的,就是線程安全的。同步
舉例 好比一個 ArrayList 類,在添加一個元素的時候,它可能會有兩步來完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。it
在單線程運行的狀況下,若是 Size = 0,添加一個元素後,此元素在位置 0,並且 Size=1; 而若是是在多線程狀況下,好比有兩個線程,線程 A 先將元素存放在位置 0。可是此時 CPU 調度線程A暫停,線程 B 獲得運行的機會。線程B也向此 ArrayList 添加元素,由於此時 Size 仍然等於 0 (注意哦,咱們假設的是添加一個元素是要兩個步驟哦,而線程A僅僅完成了步驟1),因此線程B也將元素存放在位置0。而後線程A和線程B都繼續運行,都增長 Size 的值。 那好,如今咱們來看看 ArrayList 的狀況,元素實際上只有一個,存放在位置 0,而 Size 卻等於 2。這就是「線程不安全」了
看完總結:線程安全--對共享的代碼(全局變量、靜態變量等)單個線程執行的結果和多個線程同時執行結果一致,兩者沒有二義性;
線程不安全--對共享的代碼(全局變量、靜態變量等)單個線程執行的結果和多個線程同時執行結果不一致,兩者有二義性,