最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java單例模式的實(shí)現(xiàn)與原理剖析

 更新時(shí)間:2022年05月11日 14:11:20   作者:Bug?終結(jié)者  
單例模式是Java中最簡單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。本文將詳解單例模式的實(shí)現(xiàn)及原理剖析,需要的可以參考一下

一、什么是單例模式

單例模式(Singleton Pattern)是 Java 中最簡單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。

這種模式涉及到一個(gè)單一的類,該類負(fù)責(zé)創(chuàng)建自己的對象,同時(shí)確保只有單個(gè)對象被創(chuàng)建。這個(gè)類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實(shí)例化該類的對象。

注意

  • 單例模式只能由一個(gè)實(shí)例對象
  • 單例類必須自己創(chuàng)建自己的唯一實(shí)例。
  • 單例類必須給所有其他對象提供這一實(shí)例。

二、哪些地方用到了單例模式

單例模式經(jīng)常用在需要一個(gè)實(shí)例的程序中,例如

1.Spring框架IOC容器就使用到了單例模式,默認(rèn)創(chuàng)建對象的時(shí)候?yàn)閱卫J?/p>

2.ResultBean 后端統(tǒng)一返回給前端的封裝類,這個(gè)在項(xiàng)目中是唯一的,只用一個(gè)對象進(jìn)行返回JSON給前端進(jìn)行渲染

JDK中也有單例模式的身影,例

  • Runtime 體現(xiàn)了餓漢式單例
  • Console 體現(xiàn)了雙檢鎖懶漢式單例
  • Collections 中的 EmptyNavigableSet 內(nèi)部類懶漢式單例
  • ReverseComparator.REVERSE_ORDER 內(nèi)部類懶漢式單例
  • Comparators.NaturalOrderComparator.INSTANCE 枚舉餓漢式單例

三、單例模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

提供了對唯一實(shí)例的訪問

可以節(jié)約系統(tǒng)資源,提高系統(tǒng)的性能,減少不必要的內(nèi)存開銷

允許可變數(shù)目的實(shí)例(多例類)

缺點(diǎn)

擴(kuò)展困難(缺少抽象層)

單例類的職責(zé)過重

由于自動垃圾回收機(jī)制,可能會導(dǎo)致共享的單例對象的狀態(tài)丟失

四、手寫單例模式

餓漢式

package com.wanshi.single;

//餓漢式單例
public class Hungry {


    //會造成資源浪費(fèi),占用CPU
    private byte[] data1 = new byte[1024*1024];
    private byte[] data2 = new byte[1024*1024];
    private byte[] data3 = new byte[1024*1024];
    private byte[] data4 = new byte[1024*1024];


    private Hungry() {
        System.out.println("Hungry init...");
    }


    private static Hungry hungry = new Hungry();

    public static Hungry getInstance() {
        return hungry;
    }
}

class Test {
	public static void main(String[] args) {
        Hungry hungry = Hungry.getInstance();
        Hungry hungry2 = Hungry.getInstance();
        System.out.println(hungry);
        System.out.println(hungry2);
    }
}

枚舉餓漢式

package com.wanshi.single;

import java.lang.reflect.Constructor;

// enum 是一個(gè)class類
public enum EnumSingle {

    INSTANCE;

    public static EnumSingle getInstance() {
        return INSTANCE;
    }
}

class Test {

    public static void main(String[] args) throws Exception{
        EnumSingle instance1 = EnumSingle.INSTANCE;
        Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class, int.class);
        declaredConstructor.setAccessible(true);

        EnumSingle instance2 = declaredConstructor.newInstance();

        System.out.println(instance1);
        System.out.println(instance2);
    }
}

在這里自行下載jad編譯工具即可

枚舉類最后反編譯源碼

jad工具反編譯

jad -sjava EnumSingle.class

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   EnumSingle.java

package com.wanshi.single;


public final class EnumSingle extends Enum
{

    public static EnumSingle[] values()
    {
        return (EnumSingle[])$VALUES.clone();
    }

    public static EnumSingle valueOf(String name)
    {
        return (EnumSingle)Enum.valueOf(com/wanshi/single/EnumSingle, name);
    }

    private EnumSingle(String s, int i)
    {
        super(s, i);
    }

    public static EnumSingle getInstance()
    {
        return INSTANCE;
    }

    public static final EnumSingle INSTANCE;
    private static final EnumSingle $VALUES[];

    static 
    {
        INSTANCE = new EnumSingle("INSTANCE", 0);
        $VALUES = (new EnumSingle[] {
            INSTANCE
        });
    }
}

DCL懶漢式

package com.wanshi.single;

public class Lazy {

    private static Lazy lazy;

    public static Lazy getInterface() {
        synchronized (Lazy.class) {
            if (lazy == null) {
                lazy = new Lazy();
            }
        }
        return lazy;
    }

    public static void main(String[] args) {
        Lazy lazy = Lazy.getInterface();
        Lazy lazy2 = Lazy.getInterface();
        System.out.println(lazy);
        System.out.println(lazy2);
    }
}

雙檢鎖懶漢式

package com.wanshi.single;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class LazyMan {


    private static boolean flag = false;

    private LazyMan() {
        synchronized (this) {
            if (!flag) {
                flag = true;
            } else {
                throw new RuntimeException("不要試圖通過反射破壞對象");
            }
        }
    }

    private volatile static LazyMan lazyMan;

    //雙重檢查鎖,懶漢式(DCL懶漢式)
    public static LazyMan getInstance() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    //不是原子性操作,1.分配內(nèi)存空間,2.執(zhí)行構(gòu)造方法,3.把對象指向這個(gè)空間 指令重排可能會發(fā)生   加上volatile關(guān)閉指令重排
                    lazyMan = new LazyMan();
                }
            }
        }
        return lazyMan;
    }

    public static void main(String[] args) throws Exception {
//        LazyMan lazyMan1 = LazyMan.getInstance();

        Field flag = LazyMan.class.getDeclaredField("flag");
        flag.setAccessible(true);


        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);

        declaredConstructor.setAccessible(true);
        LazyMan lazyMan1 = declaredConstructor.newInstance();
        flag.set(lazyMan1, false);
        LazyMan lazyMan2 = declaredConstructor.newInstance();
        System.out.println(lazyMan1);
        System.out.println(lazyMan2);
    }
}

為什么要使用 volatile 關(guān)鍵字呢

不是原子性操作

1.分配內(nèi)存空間

2.執(zhí)行構(gòu)造方法

3.把對象指向這個(gè)空間

指令重排可能會發(fā)生 加上volatile關(guān)閉指令重排

內(nèi)部類懶漢式

package com.wanshi.single;

public class Holder {

    private Holder() {

    }

    public static class InnerClass {
        private static final Holder HOLDER = new Holder();
    }
}

案例全部通過測試!

小結(jié)

單例模式共有5種創(chuàng)建方式,分別為餓漢式、DCL懶漢式、雙檢鎖懶漢式、Enum枚舉餓漢式,內(nèi)部類懶漢式,這幾種方式要掌握,項(xiàng)目中對于全局唯一的對象將其封裝為單例模式,開箱即用,非常方便,以及面試中,會讓手寫單例模式,可謂是大廠必備!

以上就是詳解Java單例模式的實(shí)現(xiàn)與原理剖析的詳細(xì)內(nèi)容,更多關(guān)于Java單例模式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

怀远县| 江陵县| 长治市| 遂川县| 东明县| 黑龙江省| 邮箱| 宜黄县| 陆丰市| 石家庄市| 松滋市| 五峰| 铅山县| 汶川县| 武邑县| 滁州市| 兴山县| 读书| 万安县| 阳春市| 荔浦县| 海原县| 当雄县| 绥阳县| 琼结县| 元朗区| 蓝山县| 海伦市| 马鞍山市| 玛多县| 皋兰县| 韶关市| 南城县| 辛集市| 板桥市| 澄迈县| 广河县| 南阳市| 琼中| 茂名市| 措美县|