1. 程式人生 > >《Java並發編程實戰》讀書筆記1_第三章:對象的共享

《Java並發編程實戰》讀書筆記1_第三章:對象的共享

相對 執行順序 調整 ava 得到 並發編程 自己 引用 處理

可見性
內存可見性,我們不僅希望防止某個線程正在使用對象狀態而另一個線程在同時修改改狀態,而且希望確保當一個線程修改了對象狀態後,其他線程能夠看到發生的狀態變化。

順序性
在沒有同步的情況下,編譯器、處理器以及運行時等都可能對操作的執行順序進行一些意想不到的調整。在缺乏足夠同步的多項成程序中,要相對內存操作的執行順序進行判斷,幾乎無法得到正確的結論。

非原子的64位操作
Java內存模型要求,變量的讀取操作和寫入操作都必須是原子操作,但對於非volatile類型的long和double變量,JVM允許將64位的讀操作或寫操作分解為兩個32位的操作。在多線程程序中使用共享且可變的long和double等類型的變量也是不安全的,除非用關鍵字volatile來聲明他們,或者用鎖保護起來。

所以加鎖的含義不僅僅局限於互斥行為,還包括內存的可見性。為了確保所有線程都能夠看到共享變量的最新值,所有執行讀操作或者寫操作的線程都必須在同一個鎖上同步。
volatile可以確保順序性和可見性,並且在性能上,讀取volatile變量的開銷比非volatile變量的開銷只大一點點

當前僅當滿足以下所有條件的時候才應該使用volatile變量

  • 對變量的寫操作不依賴變量的當前值,或者你能確保只有單個線程更新變量的值。
  • 該變量不會與其他狀態變量一起納入不變性條件中。
  • 在訪問變量時不需要加鎖。

發布和逃逸
“發布”一個對象的意思是指,是對象能夠在當前作用域之外的代碼中使用。例如,將一個紙箱該對象的引用保存到其他代碼可以訪問的地方,或者在某一個非私有的方法中返回該引用,或者將引用傳遞到其他類的方法中。

當某個不應該發布的對象被發布時,這種情況就被成為逃逸。
不要再構造過程中使用this引用逃逸。

ThreadLocal
這個類能使線程中的某個值與保存值的對象關聯起來,即線程有自己的數據空間。當某個頻繁執行的操作需要一個臨時對象,而同時希望有避免在每次執行時對重新分配該臨時對象,就可以用這個,可以保證線程的封閉性。
但是,這個無疑使代碼和框架耦合在一起。

不變性

不變性對象一定是線程安全的,不變性對象需要滿足下面三個條件

  • 對象創建之後其狀態不可改變
  • 對象的所域都是final類型。
  • 對象是正確創建的,構造方法中沒有使用this引用。

《Java並發編程實戰》讀書筆記1_第三章:對象的共享