本想吟詩一首,奈何才疏學淺。
吼吼得了
/**
* 加鎖懶漢式單例模式
* 犧牲了性能(初始化後,仍會發生線程阻塞問題),保證了併發安全
*/
class SingleInstance2 {
private static SingleInstance2 singleInstance2;
public static synchronized SingleInstance2 getSingleInstance2(){
if (singleInstance2 == null) {
singleInstance2 = new SingleInstance2();
}
return singleInstance2;
}
}
/**
* 加鎖懶漢式單例模式
* 犧牲了性能(初始化後,仍會發生線程阻塞問題),保證了併發安全
*/
class SingleInstance2 {
private static SingleInstance2 singleInstance2;
public static synchronized SingleInstance2 getSingleInstance2(){
if (singleInstance2 == null) {
singleInstance2 = new SingleInstance2();
}
return singleInstance2;
}
}
/**
* 餓漢式,既能保證併發安全,也能保證性能
* 缺點:類加載時就初始化,浪費內存
*/
class SingleInstance3 {
private static final SingleInstance3 singleInstance3 = new SingleInstance3();
public static SingleInstance3 getSingleInstance3() {
return singleInstance3;
}
}
* 餓漢式,既能保證併發安全,也能保證性能
* 缺點:類加載時就初始化,浪費內存
*/
class SingleInstance3 {
private static final SingleInstance3 singleInstance3 = new SingleInstance3();
public static SingleInstance3 getSingleInstance3() {
return singleInstance3;
}
}
volatile/單例模式 學習筆記
/**
* 雙重檢查鎖機制,兼顧性能與安全,初始化以後,不會發生線程阻塞
* Java指令執行的過程:1.將變量從主存複製到線程的工做內存中;2.而後進行讀操做;3.有賦值指令時進行賦值操做;4.將結果寫入主存中;
* 以上4步都是原子性的,但組合到一塊兒,多線程操做時不能保證總體原子性,這也就是線程併發安全問題的緣由。
* 其中volatile修飾詞做用:
* 1.某一線程對volatile修飾的變量進行修改後,會強制將結果寫入主存,並使其它線程緩存行失效(失效後,讀操做不能從工做內存中直接讀取,從步驟1開始),
* 即保證3和4指令執行過程的總體原子性,並通知其它線程。
* 2.禁止指令重排(代碼的編寫順序和指令執行的順序不一致),必定程度上保證了有序性。
* @author: dreamMaker
**/
public class SingleInstance {
private static volatile SingleInstance singleInstance;
public static SingleInstance getSingleInstance(){
//非空則跳過,由於只有首次初始化纔有安全問題,保證了初始化以後,線程不會阻塞,提升了性能
if (singleInstance == null) {
synchronized(SingleInstance.class){
//voliatile能保證可見性,但不能保證原子性,加鎖保證線程併發狀況下,也只有一個實例
if (singleInstance == null) {
singleInstance = new SingleInstance();
}
}
}
return singleInstance;
}
}
/**
* 雙重檢查鎖機制,兼顧性能與安全,初始化以後,不會發生線程阻塞
* Java指令執行的過程:1.將變量從主存複製到線程的工做內存中;2.而後進行讀操做;3.有賦值指令時進行賦值操做;4.將結果寫入主存中;
* 以上4步都是原子性的,但組合到一塊兒,多線程操做時不能保證總體原子性,這也就是線程併發安全問題的緣由。
* 其中volatile修飾詞做用:
* 1.某一線程對volatile修飾的變量進行修改後,會強制將結果寫入主存,並使其它線程緩存行失效(失效後,讀操做不能從工做內存中直接讀取,從步驟1開始),
* 即保證3和4指令執行過程的總體原子性,並通知其它線程。
* 2.禁止指令重排(代碼的編寫順序和指令執行的順序不一致),必定程度上保證了有序性。
* @author: dreamMaker
**/
public class SingleInstance {
private static volatile SingleInstance singleInstance;
public static SingleInstance getSingleInstance(){
//非空則跳過,由於只有首次初始化纔有安全問題,保證了初始化以後,線程不會阻塞,提升了性能
if (singleInstance == null) {
synchronized(SingleInstance.class){
//voliatile能保證可見性,但不能保證原子性,加鎖保證線程併發狀況下,也只有一個實例
if (singleInstance == null) {
singleInstance = new SingleInstance();
}
}
}
return singleInstance;
}
}
可能會用雙重所機制爲何要加volatile的疑問,提示:volatile會使其它線程的緩存行失效,讀操做須要從從新存中去取。