JUC多執行緒及高併發5 volatile

2021-10-01 05:06:07 字數 2267 閱讀 2028

分倆個方面:

1.單例模式dcl**:

之前的單例模式:懶漢式,餓漢式。下面舉例:

乙個執行緒訪問:

package jmm;

public class singletondemo

//3.取值

public static singletondemo getinstance ()

return instance;

}public static void main(string args)

}

main	我是構造方法singletondemo()

true

true

true

process finished with exit code 0

當多個執行緒時:

(這裡是假如有十個)

public static void main(string args) ,string.valueof(i)).start();

}

1	我是構造方法singletondemo()

3 我是構造方法singletondemo()

2 我是構造方法singletondemo()

process finished with exit code 0

這裡違背了單例模式,需要解決的問題所在,

可以用synchronized(加在這裡是把singletondemo getinstance ()下的全部鎖住)解決

public static synchronized singletondemo getinstance () 

return instance;

}

但是現在比較常用的是單例模式dcl來解決。

在高併發下來解決:使用單例的dcl:

package jmm;

public class singletondemo

//3.取值

//一、dcl(doouble check lock 雙端檢鎖機制)

public static singletondemo getinstance () }}

return instance;

}public static void main(string args) ,string.valueof(i)).start();}}

}

但是dcl(雙端檢鎖)機制不一定執行緒安全,原因是有指令重排的存在,需要加入volatile可以禁止指令重排

原因在於某乙個執行緒執行到第一次檢測,讀取到instance不為null時,instance的引用物件可能沒有完成初始化。

instance=new singletondemo();
可以分為3步完成(偽**)

memory =allocate();//1.分配物件記憶體空間

instance(memory);//2.初始化物件

instance =memory;//3.設定instance指向剛分配的記憶體位址,此時instance !=null

步驟2和步驟3不存在資料依賴關係,而且無論重排前還是重排後程式的執行結果在單執行緒中並沒有改變

因此這種重排優化是允許的。

memory =allocate();//1.分配物件記憶體空間

instance =memory;//3.設定instance指向剛分配的記憶體位址,此時instance !=null    但是物件還沒有初始化完成

instance(memory);//2.初始化物件

但是指令重排只會保證序列語義的執行的一致性(單執行緒),但多執行緒的語義不一定。

所以當一條執行緒訪問instance不為null時,由於instance例項未必已初始化完成,也就造成了執行緒安全問題。

為了解決執行緒安全問題,需要加volatile

package jmm;

public class singletondemo

//3.取值

//一、dcl(doouble check lock 雙端檢鎖機制)

public static singletondemo getinstance () }}

return instance;

}public static void main(string args) ,string.valueof(i)).start();}}

}

多執行緒高併發

修飾靜態方法鎖的是class,非靜態鎖方法鎖的是this,只有拿到這個物件才可以繼續執行 synchronized是可重入鎖 執行緒1的方法1呼叫執行緒2的方法2,判斷是同一把鎖,在同乙個執行緒,可以呼叫。synchronized的鎖公升級 hotsport 鎖公升級過程 保證執行緒可見性 mesi...

多執行緒高併發

個人總結,帶有個人主觀,請選擇性 1,實現 runable 2,使用 thread 3,執行緒池建立 executorse newcachedthreadpool 其實哪有那麼多建立方式,本質上都是實現了runable 介面。只列出大部分使用的方法,並未代表所有執行緒方法,後續會新增實際的例子,以供...

高併發和多執行緒

高併發和多執行緒 總是被一起提起,給人感覺兩者好像相等,實則高併發 多執行緒 多執行緒是完成任務的一種方法,高併發是系統執行的一種狀態,通過多執行緒有助於系統承受高併發狀態的實現。高併發是一種系統執行過程中遇到的一種 短時間內遇到大量操作請求 的情況,主要發生在web系統集中大量訪問或者socket...