Java線程同步問題產生的根源
1,緩存的引入:
計算機的運算任務不可能只靠處理器計算就能完成,處理器至少要與內存交互。由於計算機的存儲設備與處理器的運算速度以幾個數量級的差距,所以現代計算機系統都不得不加入一層讀寫速度盡可能接近處理器運算速度的高速緩存來作為內存與處理器之間的緩沖:將運算需要使用的數據復制到緩存中,讓運算能快速進行,當運算結束後再從緩存同步回內存中,這樣處理器就無需等待緩慢的內存讀寫了。基於高速緩存的存儲交互很好地解決了處理器與內存的速度矛盾,但是也為計算機系統帶來了更高的復雜度,因為它引入了一個新問題:緩存一致性。在多處理器系統中,每個處理器都有自己的高速緩存,而他們又共享同一主內存,當多個處理器的運算任務都涉及同一塊主內存區域時,將可能導致各自的緩沖數據不一致。而Java正是通過共享內存的方式進行線程間的通信的,所以線程同步問題隨之而來。
2,重排序:
為了使處理器內部的運算單元能盡量被充分利用,處理器可能會對輸入代碼進行亂序執行優化,處理器會在計算之後將亂序執行的結果重組,保證該結果與順序執行的結果是一致的,但並不保證程序中各個語句計算的先後順序與輸入代碼中的順序一致,因此,如果存在一個計算任務依賴另外一個計算任務的中間結果,那麽其順序性並不能靠代碼的先後順序來保證。與處理器的亂序執行優化類似,Java虛擬機的即時編譯器中也有類似的執行重排序。也就是說為了優化程序性能編譯器和處理器會對指令序列進行重排序。如果兩個操作訪問同一個變量,且這兩個操作中有一個為寫操作,此時這兩個操作之間就存在數據依賴性。JMM保證在單線程程序中如果兩個操作存在依賴性那麽編譯器和處理器不會對其進行重排序,但是不同處理器之間和不同線程之間的數據依賴性不被編譯器和處理器考慮。
本文出自 “埃文” 博客,請務必保留此出處http://wenshengzhu.blog.51cto.com/5151285/1983328
Java線程同步問題產生的根源