更新時(shí)間:2020年09月29日10時(shí)27分 來源:傳智播客 瀏覽次數(shù):
(1)問題分析:
主要考察懶漢和餓漢模式在創(chuàng)建時(shí)的區(qū)別以及分別在什么情況下使用懶漢模式,什么情況下使用餓漢模式。
懶漢模式:在類加載的時(shí)候不被初始化。
餓漢模式:在類加載時(shí)就完成了初始化,但是加載比較慢,獲取對(duì)象比較快。
餓漢模式是線程安全的,在類創(chuàng)建好一個(gè)靜態(tài)對(duì)象提供給系統(tǒng)使用,懶漢模式在創(chuàng)建對(duì)象時(shí)不加上synchronized,會(huì)導(dǎo)致對(duì)象的訪問不是線程安全的。
(2)核心答案講解:
餓漢式:
public class Singleton{
? private static Singleton singleton = new Singleton ();
? private Singleton (){}
? public static Singleton getInstance(){return singletion;}
? }
懶漢式:
public class Singleton{
? private static Singleton singleton = null;
? public static synchronized synchronized getInstance(){
? if(singleton==null){
? singleton = new Singleton();
? }
? return singleton;
? }
? }
餓漢式是線程安全的,在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用,以后不在改變
懶漢式如果在創(chuàng)建實(shí)例對(duì)象時(shí)不加上synchronized則會(huì)導(dǎo)致對(duì)對(duì)象的訪問不是線程安全的。
從實(shí)現(xiàn)方式來講他們最大的區(qū)別就是懶漢式是延時(shí)加載,是在需要的時(shí)候才創(chuàng)建對(duì)象,而餓漢式在虛擬機(jī)啟動(dòng)的時(shí)候就會(huì)創(chuàng)建。
(3)問題擴(kuò)展
懶漢式不會(huì)預(yù)先創(chuàng)建對(duì)象,只在第一次調(diào)用時(shí)才創(chuàng)建對(duì)象,但是多線程并發(fā)執(zhí)行的時(shí)候就很容易出現(xiàn)安全隱患,比如說第一個(gè)線程在判斷newInstance == null時(shí),還沒有new出實(shí)例時(shí),第二個(gè)線程也進(jìn)來,判斷的newInstance也是null,然后也會(huì)new出實(shí)例,這就不符合單例模式了, 所以需要加鎖。使用synchronized關(guān)鍵字加鎖能解決安全問題,但是加鎖同時(shí)會(huì)出現(xiàn)一個(gè)問題,那就是每次都需要判斷鎖,這樣性能就會(huì)降低,所以為了提高性能,我們應(yīng)該盡量減少鎖判斷的次數(shù),加上雙重判斷。
//靜態(tài)工廠方法、單鎖
public synchronized static SingletonTest2 getInstance1() {
? if (single2==null) {
? single2 = new SingletonTest2();
? }
? return single2;
}
?
//靜態(tài)工廠方法、雙重鎖
public static SingletonTest2 getInstance2() {
? if (single2==null) {
? synchronized (SingletonTest2.class) {
? if (single2==null) {
? single2 = new SingletonTest2();
? }
? }
? }
? return single2;
}
(4)結(jié)合項(xiàng)目中的使用
懶漢式的特點(diǎn)是延遲加載,比如配置文件,采用懶漢式的方法。
猜你喜歡
北京校區(qū)