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

JAVA設計模式之單例模式詳解

 更新時間:2022年01月28日 16:49:38   作者:JinziH Never Give Up  
大家好,本篇文章主要講的是JAVA設計模式之單例模式詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下

前言

在之前的文章里已經介紹了設計模式以及設計原則的概念,接下來我們從單例模式入手深入學習幾種常用的JAVA設計模式,在實踐中加深理解。

一、單例模式是什么?

單例(Singleton)模式的定義:指一個類只有一個實例,且該類能自行創(chuàng)建這個實例的一種模式。

作用:單例模式是保證系統實例唯一性的重要手段。用于一個全局類對象在多個地方被使用的場景下,保障了整個系統只有一個對象被使用,很好的節(jié)約了資源

實現方法:將類的實例化方法私有化來防止程序通過其他方式創(chuàng)建該類的實例,提供一個全局唯一獲取該類實例的方法幫助用戶獲取類的實例。

實現單例模式很簡單,每次獲取前先判斷系統是否已經存在單例對象,沒有就創(chuàng)建,有就返回這個對象。單例模式常見的寫法有懶漢式單例和餓漢式單例。

二、懶漢式單例

定義:類加載時沒有生成單例,第一次調用 getlnstance 方法時創(chuàng)建這個單例。

public class LazySingleton {

    //定義一個私有的靜態(tài)對象instance,靜態(tài)方法和屬性屬于類,能保障單例對象的唯一性
    private static LazySingleton instance;

    //私有化構造方法,只能在本類中被訪問,其他類中不能通過構造方法直接創(chuàng)建對象
    private LazySingleton() {
    }

    //提供一個全局唯一獲取實例的方法
    public static synchronized LazySingleton getInstance(){
        if(instance==null){
            instance=new LazySingleton();
        }
        return instance;
    }
}

懶漢模式在獲取對象實例時做了加鎖操作,因此是線程安全的

測試代碼與結果

public class TestLazySingleton {
    public static void main(String[] args) {
        LazySingleton lazySingleton1=LazySingleton.getInstance();
        LazySingleton lazySingleton2=LazySingleton.getInstance();
        LazySingleton lazySingleton3=LazySingleton.getInstance();
        System.out.println(lazySingleton1);
        System.out.println(lazySingleton2);
        System.out.println(lazySingleton3);
    }
}

在這里插入圖片描述

從上圖中可以看出雖然獲取了三次實例,但每次獲取的都是同一個實例,即一個類只有一個實例。

三、餓漢式單例

定義:該模式的特點是類一旦加載就創(chuàng)建一個單例,在調用 getInstance 方法之前單例已經存在。

public class HungrySingleton {
    //類加載完成后該類的實例便已經存在
    private static HungrySingleton instance=new HungrySingleton();
    //私有化構造方法
    private HungrySingleton(){
    }
    //類加載后實例就存在,不會出現線程安全問題,不需要加鎖
    public static HungrySingleton getInstance(){
        return  instance;
    }
}

測試代碼和結果

public class TestHungrySingleton {
    public static void main(String[] args) {
       HungrySingleton hungrySingleton1=HungrySingleton.getInstance();
       HungrySingleton hungrySingleton2=HungrySingleton.getInstance();
       HungrySingleton hungrySingleton3=HungrySingleton.getInstance();
        System.out.println(hungrySingleton1);
        System.out.println(hungrySingleton2);
        System.out.println(hungrySingleton3);
    }
}

在這里插入圖片描述

從上圖看出餓漢式單例在整個運行過程中也只存在一個實例。

懶漢式單例和餓漢式單例的區(qū)別
1.懶漢模式在類中定義了單例但是并未實例化,實例化是在方法中實現的,而餓漢模式定義的時候就進行了實例化
2.懶漢模式需要在獲取實例的方法上加鎖保證線程安全,餓漢模式不需要加鎖。

四、雙重校驗鎖

懶漢模式用到了synchronized,會導致很大的性能開銷,并且加鎖其實只需要在第一次初始化的時候用到,之后的調用都沒必要再進行加鎖。

雙重校驗鎖在懶漢模式的基礎上做了進一步的優(yōu)化,給靜態(tài)對象加上volatile來保證有序性,第一次獲取對象時通過synchronize(Singleton.class)保障操作的唯一性。

public class LockSingleton {
    private  volatile static LockSingleton lockSingleton;
    private LockSingleton(){}
    public static LockSingleton getInstance(){
        if(lockSingleton==null){
            synchronized (LockSingleton.class){
                if (lockSingleton==null){
                    lockSingleton=new LockSingleton();
                }
            }
        }
        return lockSingleton;
    }
}

測試代碼與結果

public class LockTest {
    public static void main(String[] args) {
        LockSingleton lockSingleton1=LockSingleton.getInstance();
        LockSingleton lockSingleton2=LockSingleton.getInstance();
        LockSingleton lockSingleton3=LockSingleton.getInstance();
        System.out.println(lockSingleton1);
        System.out.println(lockSingleton2);
        System.out.println(lockSingleton3);
    }
}

在這里插入圖片描述

執(zhí)行雙重檢查是因為,如果多個線程同時了通過了第一次檢查,并且其中一個線程首先通過了第二次檢查并實例化了對象,那么剩余通過了第一次檢查的線程就不會再去實例化對象。

除了第一次創(chuàng)建實例的時候會出現加鎖的情況,后續(xù)的所有調用都會避免加鎖而直接返回,解決了性能消耗的問題。

總結

關于單例模式本文介紹了懶漢模式、餓漢模式和雙重校驗鎖。懶漢和餓漢模式的最大區(qū)別是定義實例的時候是否進行實例化。雙重校驗鎖是對懶漢模式的優(yōu)化,解決了性能消耗的問題。

到此這篇關于JAVA設計模式之單例模式詳解的文章就介紹到這了,更多相關JAVA單例模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringSecurity多表多端賬戶登錄的實現

    SpringSecurity多表多端賬戶登錄的實現

    本文主要介紹了SpringSecurity多表多端賬戶登錄的實現
    2024-05-05
  • java?WebSocket?服務端實現代碼

    java?WebSocket?服務端實現代碼

    WebSocket協議是基于TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發(fā)送信息給客戶端,這篇文章主要介紹了java?WebSocket?服務端代碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • idea中git如何刪除commit提交的log信息

    idea中git如何刪除commit提交的log信息

    這篇文章主要介紹了idea中git如何刪除commit提交的log信息問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • SpringMvc請求處理參數?和?響應數據處理的示例詳解

    SpringMvc請求處理參數?和?響應數據處理的示例詳解

    這篇文章主要介紹了SpringMvc請求處理參數和響應數據處理,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • SpringBoot整合ActiveMQ過程解析

    SpringBoot整合ActiveMQ過程解析

    這篇文章主要介紹了SpringBoot整合ActiveMQ過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • springboot實現多文件上傳功能

    springboot實現多文件上傳功能

    這篇文章主要為大家詳細介紹了springboot實現多文件上傳功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • SpringBoot接口請求入參和出參增強的五種方法

    SpringBoot接口請求入參和出參增強的五種方法

    這篇文章主要介紹了SpringBoot接口請求入參和出參增強的五種方法,使用`@JsonSerialize`和`@JsonDeserialize`注解,全局配置Jackson的`ObjectMapper`,使用`@ControllerAdvice`配合`@InitBinder`,自定義HttpMessageConverter和使用AOP進行切面編程,需要的朋友可以參考下
    2024-07-07
  • Java線程池隊列LinkedTransferQueue示例詳解

    Java線程池隊列LinkedTransferQueue示例詳解

    這篇文章主要為大家介紹了Java線程池隊列LinkedTransferQueue示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • IDEA?Eval?Reset?使用方法匯總

    IDEA?Eval?Reset?使用方法匯總

    本文給大家介紹了IDEA?Eval?Reset?使用方法,安裝插件包括離線安裝方式和在線安裝方式,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • SpringBoot集成POI導出Execl表格之統一工具類

    SpringBoot集成POI導出Execl表格之統一工具類

    這篇文章主要為大家詳細介紹了SpringBoot集成POI導出Execl表格之統一工具類,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09

最新評論

镇坪县| 安岳县| 新津县| 郯城县| 定远县| 苏尼特左旗| 行唐县| 永泰县| 邹平县| 清镇市| 礼泉县| 察隅县| 滦平县| 天台县| 瓮安县| 济宁市| 桂东县| 贵溪市| 呼伦贝尔市| 南丹县| 清丰县| 浦县| 公主岭市| 广西| 文昌市| 新巴尔虎右旗| 南昌县| 健康| 盐城市| 宁乡县| 山丹县| 盐山县| 奎屯市| 大石桥市| 衡阳县| 许昌市| 越西县| 五峰| 忻州市| 健康| 赫章县|