Java單例模式

餓漢式

//餓漢式單例 可能會(huì)浪費(fèi)空間 還沒(méi)使用的時(shí)候已經(jīng)初始化了
//單例自己實(shí)例化自己,構(gòu)造器必須私有
public class Hungry {
    private Hungry(){
    }

    private final static Hungry hungry = new Hungry();

    public static  Hungry  getInstance(){
        return hungry;
    }

}

懶漢式DCL (double-check-lock)

//懶漢式單例
public class Lazzy {

    private Lazzy(){
        System.out.println(Thread.currentThread().getName()+":ok");
    }

    public volatile static Lazzy lazzy;

    //雙檢鎖 DCL
    public static Lazzy getInstance(){
        if(lazzy == null){
            synchronized (Lazzy.class){
                if(lazzy == null){
                    lazzy =  new Lazzy();
                    //new 一個(gè)對(duì)象非原子性操作颜骤,可能會(huì)有指令重排的現(xiàn)象
                    /**
                        new一個(gè)對(duì)象的過(guò)程
                        1:分配內(nèi)存空間
                        2:執(zhí)行構(gòu)造方法筒严,初始化對(duì)象
                        3:把對(duì)象指向1的空間
                        執(zhí)行順序123榕订,也有可能順序是 132岳瞭;
                        A線程執(zhí)行完 1搔驼、3 的時(shí)候鹃彻;
                        B線程進(jìn)來(lái)了,會(huì)發(fā)現(xiàn) 第一個(gè)判斷 lazzy != null, 會(huì)直接返回一個(gè)未初始化完成的對(duì)象筒占;
                     所以單例使用雙檢鎖酒甸,要避免當(dāng)前對(duì)象指令重排;使用volatile
                     */
                }
            }
        }
        return lazzy;
    }

//    //單線程環(huán)境下沒(méi)問(wèn)題
//    public static Lazzy getInstance(){
//        if(lazzy == null){
//            //多個(gè)線程代碼可以同時(shí)進(jìn)入這里
//            lazzy =  new Lazzy();
//        }
//        return lazzy;
//    }

    public static void main(String[] args) {
        for (int i=0; i<100; i++) {
         new Thread(()->{
             Lazzy.getInstance();
         }).start();
        }
    }
public class Holder {
    //靜態(tài)內(nèi)部類實(shí)現(xiàn)單列
    private Holder() {
    }

    public static Holder getInstance(){
        return InnerHolder.holder;
    }

    public static class InnerHolder{
        private static final Holder holder = new Holder();
    }

}

以上都可以被反射機(jī)制破壞 反射可以拿到private的空參構(gòu)造方法赋铝,改變私有權(quán)限

  //反射插勤!
    public static void main(String[] args) throws Throwable {
        Lazzy instance = Lazzy.getInstance();
        Constructor<Lazzy> declaredConstruct = Lazzy.class.getDeclaredConstructor(null);
        declaredConstruct.setAccessible(true);
        Lazzy instance2 = declaredConstruct.newInstance();

    }
//枚舉單例 枚舉實(shí)質(zhì)上也是個(gè)class是天然的單例, 繼承了Enum
public enum EnumSingle {

    INSTANCE;

    public EnumSingle getInstance(){
        return INSTANCE;
    }
}

枚舉為什么不能被反射破壞?
答:jdk的源碼有限制,不能以反射的方式創(chuàng)建枚舉 Cannot reflectively create enum objects

    @CallerSensitive
    public T newInstance(Object ... initargs)
        throws InstantiationException, IllegalAccessException,
               IllegalArgumentException, InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, null, modifiers);
            }
        }
        if ((clazz.getModifiers() & Modifier.ENUM) != 0)
            throw new IllegalArgumentException("Cannot reflectively create enum objects");
        ConstructorAccessor ca = constructorAccessor;   // read volatile
        if (ca == null) {
            ca = acquireConstructorAccessor();
        }
        @SuppressWarnings("unchecked")
        T inst = (T) ca.newInstance(initargs);
        return inst;
    }
  • 為什么有人說(shuō) 實(shí)現(xiàn)接口是枚舉單例的最佳方式?农尖?
// 定義單例模式中需要完成的代碼邏輯
public interface MySingleton {
    void doSomething();
}

public enum Singleton implements MySingleton {
    INSTANCE {
        @Override
        public void doSomething() {
            System.out.println("complete singleton");
        }
    };

    public static MySingleton getInstance() {
        return Singleton.INSTANCE;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末析恋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盛卡,更是在濱河造成了極大的恐慌助隧,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滑沧,死亡現(xiàn)場(chǎng)離奇詭異并村,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)滓技,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門哩牍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人令漂,你說(shuō)我怎么就攤上這事膝昆。” “怎么了叠必?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵荚孵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我纬朝,道長(zhǎng)收叶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任共苛,我火速辦了婚禮判没,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘俄讹。我一直安慰自己,他們只是感情好绕德,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布患膛。 她就那樣靜靜地躺著,像睡著了一般耻蛇。 火紅的嫁衣襯著肌膚如雪踪蹬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天臣咖,我揣著相機(jī)與錄音跃捣,去河邊找鬼。 笑死夺蛇,一個(gè)胖子當(dāng)著我的面吹牛疚漆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼娶聘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼闻镶!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起丸升,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤铆农,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后狡耻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墩剖,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年夷狰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岭皂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡孵淘,死狀恐怖蒲障,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瘫证,我是刑警寧澤揉阎,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站背捌,受9級(jí)特大地震影響毙籽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毡庆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一坑赡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧么抗,春花似錦毅否、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至吞琐,卻和暖如春捆探,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背站粟。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工黍图, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奴烙。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓助被,卻偏偏與公主長(zhǎng)得像剖张,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恰起,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • ①餓漢式 一上來(lái)就把對(duì)象new出來(lái)修械,并用static final修飾,通過(guò)getInstance方法返回該對(duì)象這種...
    燚旻阿閱讀 256評(píng)論 0 0
  • 首先什么是單例检盼?就一條基本原則肯污,單例對(duì)象的類只會(huì)被初始化一次。在 Java 中吨枉,我們可以說(shuō)在 JVM 中只存在該類...
    woshishui1243閱讀 175評(píng)論 0 0
  • 簡(jiǎn)介 單例模式是應(yīng)用最廣的模式之一,它是為了確保某一個(gè)類在一個(gè)java虛擬機(jī)(進(jìn)程)中有且只有一個(gè)實(shí)例存在. 帶來(lái)...
    JimmieYang閱讀 2,103評(píng)論 0 15
  • 單例模式是我們實(shí)際開發(fā)中常用到的開發(fā)模式蹦渣,目的是保證實(shí)例的唯一性,確保這個(gè)類在內(nèi)存中只會(huì)存在一個(gè)對(duì)象貌亭,但我們現(xiàn)在用...
    薛之濤閱讀 1,976評(píng)論 1 2
  • 應(yīng)用最廣的模式——單例模式 一劣挫、單例模式的定義和關(guān)鍵點(diǎn) 定義確保一個(gè)類只有一個(gè)實(shí)例對(duì)象雳刺,而且自行實(shí)例化向整個(gè)系統(tǒng)提...
    zoustin閱讀 445評(píng)論 0 1