高并发单例模式
如果在高并發(fā)時(shí)候,使用這種單例模式?
publci class Singleton{?
???? private static Singleton instance = null;?
???? private Singleton(){}?
???? public static Singleton getInstance(){?
??????????? if(instance == null){?
?????????????????? instance = new Singleton();?
??????????? }?
??????????? return instance;?
??? }?
}?
可能會(huì)出現(xiàn)多個(gè)指向改類的對(duì)象,這是什么情況呢??
?
從上面圖可以看到,在1、2情況都沒(méi)有創(chuàng)建對(duì)象,到了3時(shí)候Thread1創(chuàng)建一個(gè)對(duì)象,而Thread2并不知道,所以在4的情況下面Thread2也創(chuàng)建了對(duì)象,所以就出現(xiàn)該類不同對(duì)象,如果是使用C++語(yǔ)言實(shí)現(xiàn)這種模式,而且沒(méi)有手工去回收就可能出現(xiàn)內(nèi)存泄露情況。解決的方法是使用關(guān)鍵字synchronized代碼如下:?
publci class Singleton{?
???? private static Singleton instance = null;?
???? private Singleton(){}?
???? public static synchronized Singleton getInstance(){?
??????????? if(instance == null){?
?????????????????? instance = new Singleton();?
??????????? }?
??????????? return instance;?
??? }?
}?
這樣一來(lái)不管多少個(gè)線程訪問(wèn)都是實(shí)現(xiàn)一個(gè)對(duì)象實(shí)例化了。但是如果使用該關(guān)鍵字可能性能方面有所降低,因?yàn)槊看卧L問(wèn)時(shí)候都只能一個(gè)線程獲取到該對(duì)象,當(dāng)出現(xiàn)多個(gè)線程訪問(wèn)時(shí)候就會(huì)出現(xiàn)排隊(duì)等待的情況,為了解決這種情況只需要在創(chuàng)建時(shí)候使用該關(guān)鍵字就可以了?
publci class Singleton{?
???? private static Singleton instance = null;?
???? private Singleton(){}?
???? public static Singleton getInstance(){?
??????????? if(instance == null){?
?????????????????? synchronized(Singleton.class){?
??????????????????????? if(instance == null)?
??????????????????????? instance = new Singleton();?
?????????????????? }???????????
???????????? }?
??????????? return instance;?
??? }?
}?
因?yàn)榈谝淮问褂迷搶?duì)象時(shí)候才需要檢查該對(duì)象是否已經(jīng)創(chuàng)建了,而第二次檢查改對(duì)象是否為空是為了避免1、2的情況,因?yàn)椴还苁荰hread1或者是Thread2拿到線程鎖都不會(huì)阻止另外的線程創(chuàng)建對(duì)象,因?yàn)榈搅?的情況中,如果Thread1已經(jīng)拿到線程鎖之后,創(chuàng)建對(duì)象但是到了Thread2獲取到線程鎖時(shí)候,也創(chuàng)建對(duì)象所以也會(huì)出現(xiàn)不同對(duì)象實(shí)例的情況,這種兩次檢查叫做double click locking模式
publci class Singleton{?
???? private static Singleton instance = null;?
???? private Singleton(){}?
???? public static Singleton getInstance(){?
??????????? if(instance == null){?
?????????????????? instance = new Singleton();?
??????????? }?
??????????? return instance;?
??? }?
}?
可能會(huì)出現(xiàn)多個(gè)指向改類的對(duì)象,這是什么情況呢??
?
從上面圖可以看到,在1、2情況都沒(méi)有創(chuàng)建對(duì)象,到了3時(shí)候Thread1創(chuàng)建一個(gè)對(duì)象,而Thread2并不知道,所以在4的情況下面Thread2也創(chuàng)建了對(duì)象,所以就出現(xiàn)該類不同對(duì)象,如果是使用C++語(yǔ)言實(shí)現(xiàn)這種模式,而且沒(méi)有手工去回收就可能出現(xiàn)內(nèi)存泄露情況。解決的方法是使用關(guān)鍵字synchronized代碼如下:?
publci class Singleton{?
???? private static Singleton instance = null;?
???? private Singleton(){}?
???? public static synchronized Singleton getInstance(){?
??????????? if(instance == null){?
?????????????????? instance = new Singleton();?
??????????? }?
??????????? return instance;?
??? }?
}?
這樣一來(lái)不管多少個(gè)線程訪問(wèn)都是實(shí)現(xiàn)一個(gè)對(duì)象實(shí)例化了。但是如果使用該關(guān)鍵字可能性能方面有所降低,因?yàn)槊看卧L問(wèn)時(shí)候都只能一個(gè)線程獲取到該對(duì)象,當(dāng)出現(xiàn)多個(gè)線程訪問(wèn)時(shí)候就會(huì)出現(xiàn)排隊(duì)等待的情況,為了解決這種情況只需要在創(chuàng)建時(shí)候使用該關(guān)鍵字就可以了?
publci class Singleton{?
???? private static Singleton instance = null;?
???? private Singleton(){}?
???? public static Singleton getInstance(){?
??????????? if(instance == null){?
?????????????????? synchronized(Singleton.class){?
??????????????????????? if(instance == null)?
??????????????????????? instance = new Singleton();?
?????????????????? }???????????
???????????? }?
??????????? return instance;?
??? }?
}?
因?yàn)榈谝淮问褂迷搶?duì)象時(shí)候才需要檢查該對(duì)象是否已經(jīng)創(chuàng)建了,而第二次檢查改對(duì)象是否為空是為了避免1、2的情況,因?yàn)椴还苁荰hread1或者是Thread2拿到線程鎖都不會(huì)阻止另外的線程創(chuàng)建對(duì)象,因?yàn)榈搅?的情況中,如果Thread1已經(jīng)拿到線程鎖之后,創(chuàng)建對(duì)象但是到了Thread2獲取到線程鎖時(shí)候,也創(chuàng)建對(duì)象所以也會(huì)出現(xiàn)不同對(duì)象實(shí)例的情況,這種兩次檢查叫做double click locking模式
總結(jié)
- 上一篇: centos安装Ambari
- 下一篇: centos安装Hue 3.7.0