volatile與synchronized

基本問題

  1. JAVA中的多線程的基本問題就是安全問題。一方面是如何防止死鎖發生,另一方面是如何保證同一資源在多個線程操作間和操作後還維持正確的狀態,即資源的狀態正確性。
  2. 資源的狀態正確性可以由對資源操作的原子性,代碼執行的順序性,和資源的可見性來共同保證。

三個性質的定義

  1. 對資源操作的原子性,即定義一種操作(由一行或多行代碼定義),在這個操作執行的任何時候都不可被中斷,要麼執行完成,要麼不執行。
  2. 代碼執行的順序性,即防止編譯器和處理器對代碼進行重排序,典型的場景就是多線程中對兩個變量的初始化順序,在後面的代碼中有對這兩個變量的使用順序有要求。
  3. 資源可見性,即資源(變量等)在內存中並非唯一一份,導致對資源的操作存在數據一致性問題。是由於java的線程內存模型中存在着工作內存和主內存,其工作內存每個線程私有一份並且其中的資源是主內存中資源的一個備份,線程直接操作工作內存的資源,之後再同步到主內存,當多個線程操作同一資源時,其本質是操作其工作內存中的資源,同時更改資源後再同步到主內存,會導致資源狀態覆蓋,也就是部分線程丟失更新。

三個性質的保證結果

  1. 保證了資源可見性,就是使得一個線程對資源的操作對其他線程可見,其本質是使得其他線程工作內存中的相同資源備份失效,強制從主內存再次拷貝最新數據以使用。
  2. 保證了原子性,就使得線程在一定粒度上的執行結果是絕對可以預見的,不可能存在意外的結果,執行即成功。
  3. 保證了代碼的順序性,就使得在代碼底層執行的順序和預期的一致,不會因爲底層的自作聰明的優化而出現意料之外的問題。
  4. 只要保證這三個性質的必要性,就可以保證資源的最終狀態正確性。

volatile與synchronized

  1. volatile 保證每次拿到最新的資源(變量),即保證的是在多線程中資源的可見性,以及部分順序性,在被它修飾的資源(變量)的相鄰的代碼的順序不會被重排序。
  2. synchronized 用於保證多線程之間的同步性,其實質是使得多線程在代碼臨界區以順序執行,任何時間在此區域執行的線程只有一個,即任何時候只有一個線程訪問和操作這個(多個)資源,也就不存在資源的狀態正確性問題。

死鎖

  1. 死鎖即多個線程對已持有的資源不釋放同時需求其他線程所持有的資源,而產生一種所有線程首尾循環持有和需求資源,並以期待需求的資源被釋放而進入無限等待狀態的情況。
  2. 死鎖產生的本質是由於多個線程對多個資源的爭奪產生的,或者說是線程對資源的使用不當產生的。需要從資源的使用方面解決。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章