關(guān)于設(shè)計(jì)模式,這其實(shí)是單獨(dú)存在的東西,它不屬于 Java,也不屬于任何語言所獨(dú)有,但是在 Java 中使用較多,所以今天小編就給大家介紹下單例設(shè)計(jì)模式中的餓漢和懶漢這倆樸素的打工人。推薦好課:Java 多線程講解、深入解析 Java 面向?qū)ο?/a>。
首先,我們先了解下單例模式的定義:單例設(shè)計(jì)模式目的是使得類的一個(gè)對象成為系統(tǒng)中的唯一實(shí)例。
再看下,Java 中單例模式的定義:一個(gè)類有且僅有一個(gè)實(shí)例,并且自行實(shí)例化向整個(gè)系統(tǒng)提供。
那么,所謂“懶漢式”與“餓漢式”的區(qū)別,是在于建立單例對象的時(shí)間不同。
“懶漢式”:是在你真正用到的時(shí)候才去建這個(gè)單例對象;
“餓漢式”:在不管你用的用不上,一開始就建立這個(gè)單例對象。
一、餓漢式
餓漢式:通俗的來講,這位打工人對干飯?zhí)胤e極,不管餓不餓都跟餓死鬼似的,老早的就把干飯工具準(zhǔn)備好了( new 對象),隨時(shí)準(zhǔn)備干飯。
上代碼:
class Hungry_people{
private int id;
private String name;
private Hungry_people(){
} //構(gòu)造器私有化
private static Hungry_people Instance=new Hungry_people();
//內(nèi)部創(chuàng)建類的對象
public static Hungry_people getInstance(){
return Instance;
}
//提供公共的靜態(tài)方法,且返回對象。
}
public class Test1 {
public static void main(String[] args) {
Hungry_people hungry1 = Hungry_people.getInstance();
Hungry_people hungry2 = Hungry_people.getInstance();
}
}
二、懶漢式
懶漢式:通俗的講,這位打工人對干飯一點(diǎn)都不上心,碗筷臟了也不理,啥時(shí)候要干飯了才來洗碗筷( new 對象)。
上代碼:
class Lazy_people {
private Lazy_people(){
}
private static Lazy_people Instance = null;
//聲明當(dāng)前對象沒有初始化值
public static Lazy_people getInstance(){
if (Instance == null){
Instance=new Lazy_people ();
//需要再造對象,不要就不new對象了
}
return Instance;
}
}
public class Test2 {
public static void main(String[] args) {
Lazy_people lazy1 = Lazy_people.getInstance();
}
}
三、餓漢和懶漢有啥不同
對于餓漢式:
優(yōu)點(diǎn):線程賊安全
缺點(diǎn):對象加載時(shí)間過長
對于懶漢式:
優(yōu)點(diǎn):延遲對象的創(chuàng)建,更快
缺點(diǎn):多線程安全賊低,但是可以通過優(yōu)化使其可用。
四、常見面試題
1.懶漢式和餓漢式有什么不同?
答:懶漢式的特點(diǎn)在于實(shí)例的延遲加載。
2.懶漢式的延遲加載有沒有問題?
答:遇到多線程訪問時(shí)會出現(xiàn)安全問題。
3.如何解決該問題?
答:可以增加同步來解決。
4.增加同步的方式?
答:用同步方法或同步代碼塊都可以,但是同步方法稍微有點(diǎn)低效。
5.增加同步時(shí),使用的鎖是哪一個(gè)?
答:該類所屬的字節(jié)碼文件對象。