中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么掌握Java的單例模式

發布時間:2022-04-14 10:14:19 來源:億速云 閱讀:157 作者:zzz 欄目:編程語言

這篇“怎么掌握Java的單例模式”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么掌握Java的單例模式”文章吧。

怎么掌握Java的單例模式

單例模式:

首先在Java中有23種設計模式:

  • 創建型模式: 工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式

  • 結構型模式: 適配器模式、裝飾者模式、代理模式、外觀模式、橋接模式、組合模式、享元模式

  • 行為型模式::策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

1、什么是單例模式:

定義:
指一個類只有一個實例,且該類能自行創建這個實例的一種模式。可以避免因打開多個任務管理器窗口而造成內存資源的浪費,或出現各個窗口顯示內容的不一致等錯誤。比如咱們電腦是不是只能打開一個任務管理器?對吧,這就是為了防止資源浪費和其他錯誤。

項目中一般可以通過單例模式來獲取同一個對象來調用工具方法,這樣的好處是節約內存資源,我沒有必要創建多個不同的對象,因為這樣消耗內存資源

簡而言之: 單例就是程序只有一個實例,該類負責創建自己的對象,同時要確保只有一個對象創建

單例模式的特點:

  1. 構造器私有

  2. 持有自己類型的屬性

  3. 對外提供獲取實例的靜態方法

單例模式的結構圖:
怎么掌握Java的單例模式

2、單例模式的優缺點:

優點:

  1. 減少了內存的開銷

  2. 避免對資源的多重占用

  3. 設置全局訪問點,可以優化和共享資源的訪問

缺點(參考自互聯網):

  1. 一般沒有接口,擴展困難。如果要擴展,則除了修改原來的代碼,沒有第二種途徑,違背開閉原則

  2. 在并發測試中,單例模式不利于代碼調試。在調試過程中,如果單例中的代碼沒有執行完,也不能模擬生成一個新的對象

  3. 單例模式的功能代碼通常寫在一個類中,如果功能設計不合理,則很容易違背單一職責原則

看一張單例模式的思維導圖:

3、懶漢模式(比較常用)

懶漢模式特征是延遲初始化,在調用方法獲取實例的時候才會實例化對象
線程不安全,嚴格意義上來說不是單例模式,優勢是在獲取實例才會創建對象因此更節省內存開銷

Demo:

public class SingLeton {

    //1、有自己類型的屬性
    private static SingLeton instance;

    //2、構造器私有化
    private SingLeton(){}

    //3、對外提供獲取實例的靜態方法
    public static SingLeton getInstance(){
        if (instance == null){
            instance = new SingLeton();
        }
        return instance;
    }}

測試類:

public class Test {
    public static void main(String[] args) {

        //判斷是否產生的是同一個對象
        SingLeton s1 = SingLeton.getInstance();
        SingLeton s2 = SingLeton.getInstance();
        System.out.println(s1 == s2);
    }}

輸出:

true

注意:

關于懶漢模式線程非安全

現在知道懶漢模式的線程是非安全的,那么就需要使用鎖(synchronized )來同步:

/**
 *   保證 instance 在所有線程中同步
 */public class SingLeton2 {

        //1、有自己類型的屬性
        private static volatile SingLeton2 instance ;    
        
        //2、構造器私有化
        private SingLeton2() {
        }

        public static synchronized SingLeton2 getInstance() {
            //getInstance 方法前加同步
            if (instance == null) {
                instance = new SingLeton2();
            }
            return instance;
        }
    }

如果是寫多線程,則不要刪除上例代碼中的關鍵字 volatile 和 synchronized,否則將存在線程非安全的問題。如果不刪除這兩個關鍵字就能保證線程安全,但是每次訪問時都要同步,會影響性能,且消耗更多的資源,這是懶漢式單例的缺點。

4、餓漢模式【推薦使用】

餓漢模式線程安全,常用,但是容易產生垃圾對象,因為餓漢模式一開始加載類的時候就初始化
了實例

Demo:

/**
 *
 * 餓漢模式
 */public class SingLeton {

    //持有自己類型的屬性   (和懶漢一樣)
    //由于static修飾,只在類加載的時候執行一次,類加載的時候就實例化對象
    private static SingLeton instance = new SingLeton();

    //構造器私有化,不能通過它創建對象
    private SingLeton(){};

    //對外提供獲取實例的靜態方法
    public static SingLeton getInstance(){
        return instance;
    }}

測試類:

public class Test {
    public static void main(String[] args) {

        //判斷是否產生的是同一個對象
        SingLeton s1 = SingLeton.getInstance();
        SingLeton s2 = SingLeton.getInstance();
        System.out.println(s1 == s2);
    }}

輸出:

true

懶漢模式和餓漢模式對比:

  1. 懶漢模式延遲加載,非線程安全,餓漢模式線程安全

  2. 懶漢模式剛運行不實例化對象,需要的時候才實例化對象,相當于來講更節省內存開銷

  3. 餓漢模式只要運行都會加載類的時候就給你初始化了,就需要使用更大的內存

圖解:
怎么掌握Java的單例模式

5、單例模式的應用場景:

  1. 需要經常創建的一些類,使用單例可以降低系統的內存壓力

  2. 這個類只要求生成一個對象的時候,比如每個人的名字

  3. 類創建實例時占用資源較多,或實例化耗時較長,且經常使用

  4. 頻繁訪問數據庫或文件的對象

  5. 類需要頻繁實例化,而創建的對象又頻繁被銷毀的時候,如多線程的線程池

6、單例模式的應用實例

這里使用懶漢式單例模式模擬產生班級的班長
分析: 在每一個學期內,班級的班長只有一人,所以適合用單例模式實現

Person類:

/**
 * 使用懶漢模式
 */public class Person {

    //保證instance在所有線程中同步
    private static volatile Person instance;

    private Person(){
        System.out.println("產生一個班長");
    }

    //加上synchronized鎖
    public static synchronized Person getInstance(){
        if(instance == null){
            instance = new Person();
        }else {
            System.out.println("錯誤信息:已經有一個班長,不能再產生");
        }
        return instance;
    }

    public void getName(){
        System.out.println("我是班長:小強");
    }}

測試類:

public class Test {
    public static void main(String[] args) {

        Person p1 = Person.getInstance();
        p1.getName(); //輸出班長名字

        Person p2 = Person.getInstance();
        p2.getName();

        if(p1 == p2){
            System.out.println("兩個班長是同一個人");
        }else {
            System.out.println("兩個班長是同一個人");

        }
    }}

運行結果:

產生一個班長
我是班長:小強
錯誤信息:已經有一個班長,不能再產生
我是班長:小強
兩個班長是同一個人

以上就是關于“怎么掌握Java的單例模式”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

东明县| 内丘县| 聂荣县| 农安县| 开原市| 葫芦岛市| 沭阳县| 镇赉县| 南川市| 安化县| 克东县| 高尔夫| 洛宁县| 郓城县| 溆浦县| 许昌市| 博罗县| 卓尼县| 美姑县| 安丘市| 钟山县| 绩溪县| 保德县| 银川市| 通城县| 盘山县| 阿拉尔市| 蓬安县| 上饶市| 屏边| 沂南县| 甘洛县| 页游| 贵港市| 霍林郭勒市| 东乌珠穆沁旗| 北川| 南城县| 东源县| 桃园县| 东辽县|