欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 實例解析單例模式

 更新時間:2021年11月01日 09:03:45   作者:FranzLiszt1847  
單例模式(Singleton Pattern)是 Java 中最簡單的設(shè)計模式之一。這種類型的設(shè)計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式,這種模式涉及到一個單一的類,該類負(fù)責(zé)創(chuàng)建自己的對象,同時確保只有單個對象被創(chuàng)建

單例模式的介紹

單例對象(Singleton)是一種常用的設(shè)計模式。在實際使用中,單例對象能保證在一個JVM中,該對象只存在一個實例存在。

優(yōu)點

1、減少系統(tǒng)開銷,提高系統(tǒng)性能
2、省去了new操作符,降低了系統(tǒng)內(nèi)存的使用頻率,減輕GC壓力
3、避免對共享資源的多重占用

缺點

1、不適應(yīng)用多變的對象
2、擴(kuò)展困難
3、單例類的職責(zé)過重,在一定程度上違背了“單一職責(zé)原則”。

Synchronized

Synchronized示例

介紹單例模式前,我們現(xiàn)介紹一下Synchronized
示例如下:
建立一個內(nèi)部類,并開啟子線程,如果實例該類,則自動執(zhí)行test1()方法

 class SynchronizedTest implements Runnable {
    private int count;

    public SynchronizedTest() {
        count = 0;
    }

    @Override
    public void run() {
        test1();
    }

    private void test1() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ":" + count++);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

構(gòu)造一個SynchronizedTest 對象,傳入兩個線程對象

 SynchronizedTest test = new SynchronizedTest();
        Thread thread1 = new Thread(test,"test1");
        Thread thread2 = new Thread(test,"test2");
        thread1.start();
        thread2.start();

由結(jié)果可知,當(dāng)一個對象持有該代碼塊時,另一個線程訪問不到被鎖住的代碼塊,只要當(dāng)前一線程執(zhí)行完成,另一線程才能執(zhí)行。

test1:0
test1:1
test1:2
test1:3
test1:4
test2:5
test2:6
test2:7
test2:8
test2:9

Synchronized與非Synchronized

建立一個內(nèi)部類

 class SynchronizedTest implements Runnable {
    private int count;

    public SynchronizedTest() {
        count = 0;
    }

    @Override
    public void run() {
        if (Thread.currentThread().getName().equals("S")) {
            test1();
        } else {
            test2();
        }
    }

    public void test1() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ":" + (count++));
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void test2() {
        for (int i = 0; i < 5; i++) {
            try {
                System.out.println(Thread.currentThread().getName() + ":" + count);
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
 }
SynchronizedTest test = new SynchronizedTest();
        Thread thread1 = new Thread(test,"S");
        Thread thread2 = new Thread(test,"N");
        thread1.start();
        thread2.start();

由結(jié)果可知,一個線程訪問Synchronized修飾的代碼塊,另一個線程訪問非Synchronized代碼塊不受阻塞

S:0
N:1
N:2
S:1
N:2
S:2
S:3
N:4
S:4
N:5

Singleton

第一個示例

此示例實現(xiàn)了單例,但是如果放在多線程當(dāng)中,將會漏洞百出
我們接著看下一個改良示例

public class Singleton {
/* 持有私有靜態(tài)實例,防止被引用,此處賦值為null,目的是實現(xiàn)延遲加載 */
private static Singleton instance = null;
    /* 私有構(gòu)造方法,防止被實例化 */
    private Singleton() {
    }
    /* 靜態(tài)工程方法,創(chuàng)建實例 */
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

第二個示例

根據(jù)第一個示例,我們進(jìn)行改良,加上Synchronized。
但是每次調(diào)用getInstance()方法時,都會對對象上鎖,為了減少系統(tǒng)開銷,我們一般在第一次創(chuàng)建對象的時候加鎖,后面就不需要了
我們接著看下一個改良示例

public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}

第三個示例

我們對上一個示例進(jìn)行改良,只有在instance == null的時候,也就是第一次創(chuàng)建對象的時候,執(zhí)行加鎖的區(qū)域。此種寫法解決了上一個示例遺留的問題,但是在Java指令中創(chuàng)建對象和賦值操作是分開進(jìn)行的,也就是說instance = new Singleton();語句是分兩步執(zhí)行的。但是JVM并不保證這兩個操作的先后順序,也就是說有可能JVM會為新的Singleton實例分配空間,然后直接賦值給instance成員,然后再去初始化這個Singleton實例。

public static Singleton getInstance() {
if (instance == null) {
synchronized (instance) {
if (instance == null) {
instance = new Singleton();
      }
   }
 }
 return instance;
}

第四個示例

此代碼初看已經(jīng)沒有問題,如果在構(gòu)造方法中出現(xiàn)異常,那么實例將得不到創(chuàng)建

public class Singleton {
/* 私有構(gòu)造方法,防止被實例化 */
private Singleton() {
}
/* 此處使用一個內(nèi)部類來維護(hù)單例 */
private static class SingletonFactory {
private static Singleton instance = new Singleton();
  }
/* 獲取實例 */
public static Singleton getInstance() {
return SingletonFactory.instance;
  }
}

第五個示例

   private static Singleton instance = null;
   private Singleton(){

    }
    public static Singleton getInstance(){
        if (instance == null){
            sync();
        }
        return instance;
    }
   private static synchronized void sync(){
        if (instance == null){
           instance = new Singleton();
            System.out.println("success");
       }
    }

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

相關(guān)文章

  • java實現(xiàn)二分法查找出數(shù)組重復(fù)數(shù)字

    java實現(xiàn)二分法查找出數(shù)組重復(fù)數(shù)字

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)二分法查找出數(shù)組重復(fù)數(shù)字,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Spring多定時任務(wù)@Scheduled執(zhí)行阻塞問題解決

    Spring多定時任務(wù)@Scheduled執(zhí)行阻塞問題解決

    這篇文章主要介紹了Spring多定時任務(wù)@Scheduled執(zhí)行阻塞問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 如何查找YUM安裝的JAVA_HOME環(huán)境變量詳解

    如何查找YUM安裝的JAVA_HOME環(huán)境變量詳解

    這篇文章主要給大家介紹了關(guān)于如何查找YUM安裝的JAVA_HOME環(huán)境變量的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • 從入門到精通:Java List遍歷修改的完全指南

    從入門到精通:Java List遍歷修改的完全指南

    在Java中,我們經(jīng)常需要遍歷List集合并對其中的元素進(jìn)行修改,這可以通過使用迭代器或for循環(huán)來實現(xiàn),需要的朋友可以參考下
    2023-10-10
  • POI通過模板導(dǎo)出EXCEL文件的實例

    POI通過模板導(dǎo)出EXCEL文件的實例

    下面小編就為大家?guī)硪黄狿OI通過模板導(dǎo)出EXCEL文件的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 詳解java 三種調(diào)用機制(同步、回調(diào)、異步)

    詳解java 三種調(diào)用機制(同步、回調(diào)、異步)

    這篇文章主要介紹了java 三種調(diào)用機制(同步、回調(diào)、異步),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Spring boot 集成 Druid 數(shù)據(jù)源過程詳解

    Spring boot 集成 Druid 數(shù)據(jù)源過程詳解

    這篇文章主要介紹了Spring boot 集成 Druid 數(shù)據(jù)源過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • Java?split方法使用超詳細(xì)講解

    Java?split方法使用超詳細(xì)講解

    這篇文章主要給大家介紹了關(guān)于Java?split方法使用的相關(guān)資料,Java中的我們可以利用split把字符串按照指定的分割符進(jìn)行分割,然后返回字符串?dāng)?shù)組,需要的朋友可以參考下
    2023-10-10
  • maven之packaging標(biāo)簽的使用

    maven之packaging標(biāo)簽的使用

    這篇文章主要介紹了maven之packaging標(biāo)簽的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Spring Boot+Shiro實現(xiàn)一個Http請求的Basic認(rèn)證

    Spring Boot+Shiro實現(xiàn)一個Http請求的Basic認(rèn)證

    本文向向大家仔細(xì)的介紹了如何使用Shiro實現(xiàn)一個Http請求的Basic認(rèn)證,有此需求的朋友可以參考下本文
    2021-06-06

最新評論