1. 程式人生 > >java併發程式設計實戰:物件的共享筆記

java併發程式設計實戰:物件的共享筆記

可見性

volatile關鍵字:
http://www.cnblogs.com/paddix/p/5428507.html

volatile關鍵字的兩層語義:
- 保證了不同執行緒對這個變數進行操作時的可見性,即一個執行緒修改了某個變數的值,這新值對其他執行緒來說是立即可見的。
- 禁止進行指令重排序。

volatile只能保證對單次讀/寫的原子性
volatile不能保證 i++ 這種的原子性。

使用場景:
雙重檢查(DCL)單例

package com.paddx.test.concurrent;

public class Singleton {
    public
static volatile Singleton singleton; /** * 建構函式私有,禁止外部例項化 */ private Singleton() {}; public static Singleton getInstance() { if (singleton == null) { synchronized (singleton) { if (singleton == null) { singleton = new Singleton(); } } } return
singleton; } }

現在我們分析一下為什麼要在變數singleton之間加上volatile關鍵字。要理解這個問題,先要了解物件的構造過程,例項化一個物件其實可以分為三個步驟:
- (1)分配記憶體空間。
- (2)初始化物件。
- (3)將記憶體空間的地址賦值給對應的引用。

但是由於作業系統可以對指令進行重排序,所以上面的過程也可能會變成如下過程:
- (1)分配記憶體空間。
- (2)將記憶體空間的地址賦值給對應的引用。
- (3)初始化物件

  如果是這個流程,多執行緒環境下就可能將一個未初始化的物件引用暴露出來,從而導致不可預料的結果。因此,為了防止這個過程的重排序,我們需要將變數設定為volatile型別的變數。
  
狀態標記量

volatile boolean inited = false;
//執行緒1:
context = loadContext();  
inited = true;            
 
//執行緒2:
while(!inited ){
sleep()
}
doSomethingwithconfig(context);

http://www.importnew.com/18126.html

釋出與逸出

釋出:使物件能夠在除當前作用域之外的地方使用。
- 將物件的引用儲存到公共靜態域。
- 在非私有方法中返回引用。
- 不要在構造過程中使this引用逸出。

**構造方法使用匿名內部類會產生溢位。**

使用工廠方法來防止。

溢位:指某個物件不應該釋出卻被髮布了。

執行緒封閉

多執行緒訪問共享資料時,通常需要同步,一種避免使用同步的方式就是不共享資料。如果僅在單執行緒裡訪問資料,那麼就不需要使用同步,這種技術被稱為執行緒封閉。

棧封閉

區域性變數訪問物件。

ThreadLocal

http://blog.csdn.net/cauchyweierstrass/article/details/48001521

不變性

不可變物件一定是執行緒安全的。

對於如何構建一個不可變物件,我們有三個條件(雖然說是”條件”,但並不是那麼硬性的,可以算是某種建議):
- 物件建立後保證狀態不可變
- 物件的所有field都是final
- 建立期間沒有逸出自身引用(this引用逸出),保證物件的建立正確。

https://www.cnblogs.com/Kavlez/p/4041395.html

不可變物件與初始化安全性