国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【單例設(shè)計(jì)模式原理詳解】Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

這篇具有很好參考價(jià)值的文章主要介紹了【單例設(shè)計(jì)模式原理詳解】Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

簡介

單例模式(Singleton Pattern)屬于創(chuàng)建型設(shè)計(jì)模式,這種模式只創(chuàng)建一個(gè)單一的類,保證一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)訪問該實(shí)例的全局節(jié)點(diǎn)。

當(dāng)您想控制實(shí)例數(shù)目,節(jié)省系統(tǒng)資源,并不想混用的時(shí)候,可以使用單例模式。單例有很多種實(shí)現(xiàn)方式,主要分為懶漢和餓漢模式,同時(shí)要通過加鎖來避免線程安全。不同語言的單例實(shí)現(xiàn)略有差異,可以通過查看不同版本的源碼來深入理解其中的差異。

?

不同語言設(shè)計(jì)模式源碼下載:https://github.com/microwind/design-pattern

作用

  1. 避免全局使用的類頻繁地創(chuàng)建與銷毀。
  2. 保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。

實(shí)現(xiàn)步驟

  1. 創(chuàng)建單例類,注意線程安全
  2. 返回全局唯一實(shí)例

UML

【單例設(shè)計(jì)模式原理詳解】Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

?

Java代碼

單例實(shí)現(xiàn),不同語言有很大不同,跟語言特性有關(guān)。請查看其他源碼進(jìn)行比較。

餓漢式(線程安全)

// SingletonEager.java 當(dāng)類被加載的時(shí)候會初始化,靜態(tài)變量被創(chuàng)建并分配內(nèi)存空間 
public class SingletonEager {
  private String name = "SingletonEager";
  // 類加載時(shí)就初始化,浪費(fèi)內(nèi)存
  private static final SingletonEager instance = new SingletonEager();

  // 構(gòu)造函數(shù)是private,不允許實(shí)例化
  private SingletonEager() {

  }
  public static SingletonEager getInstance() {
    return instance;
  }

  public void run() {
    System.out.println("SingletonEager::run() " + this.name);
  }
}

飽漢式

// SingletonLazy.java 懶漢式也叫飽漢式,增加synchronized來保證線程安全
public class SingletonLazy {

  private static SingletonLazy instance;
  private String name;

  private SingletonLazy() {

  }

  // 類初始化時(shí),靜態(tài)變量static的instance未被創(chuàng)建并分配內(nèi)存空間
  // 當(dāng)getInstance方法第一次被調(diào)用時(shí),再初始化instance變量,并分配內(nèi)存
  // 相當(dāng)于延遲到調(diào)用時(shí)再實(shí)例化,加synchronized以便線程安全,不加則存在并發(fā)時(shí)多個(gè)實(shí)例的情形
  public static synchronized SingletonLazy getInstance(String name) {
    if (instance == null) {
      instance = new SingletonLazy();
      instance.name = name;
    }
    return instance;
  }

  public void run() {
    System.out.println("SingletonLazy::run() " + this.name);
  }
}

靜態(tài)內(nèi)部類

// SingletonInner.java 靜態(tài)內(nèi)部類方式,既實(shí)現(xiàn)延遲加載,也保障線程安全。
public class SingletonInner {

  private String name;

  private SingletonInner() {

  }

  // 靜態(tài)內(nèi)部類利用了類加載初始化機(jī)制,外部類加載時(shí),并不會加載內(nèi)部類,也不會執(zhí)行
  // 虛擬機(jī)會保證方法在多線程環(huán)境下使用加鎖同步,只會執(zhí)行一次,因此線程安全
  private static class Inner {
    private static final SingletonInner instance = new SingletonInner();
  }

  // 當(dāng)執(zhí)行g(shù)etInstance()方法時(shí),虛擬機(jī)才會加載靜態(tài)內(nèi)部類
  public static SingletonInner getInstance(String name) {
    if (Inner.instance.name == null) {
      Inner.instance.name = name;
    }
    return Inner.instance;
  }

  public void run() {
    System.out.println("SingletonInner::run() " + this.name);
  }
}

雙重檢驗(yàn)懶漢

// SingletonDoubleCheck.java 雙重檢驗(yàn)懶漢單例,單例模式最優(yōu)方案,線程安全并且效率高 
public class SingletonDoubleCheck {

  // 定義一個(gè)靜態(tài)私有變量(不初始化,不使用final關(guān)鍵字)
  // 可以使用volatile保證多線程訪問時(shí)變量的可見性
  // 這樣避免了初始化時(shí)其他變量屬性還沒賦值完時(shí),被另外線程調(diào)用
  private static volatile SingletonDoubleCheck instance;
  private String name;
  private SingletonDoubleCheck() {

  }

  // 延遲到調(diào)用時(shí)實(shí)例化
  public static SingletonDoubleCheck getInstance(String name) {
    if (instance == null) {
      // 在實(shí)例化時(shí)再synchronized
      synchronized (SingletonDoubleCheck.class) {
        if (instance == null) {
          instance = new SingletonDoubleCheck();
          instance.name = name;
        }
      }
    }
    return instance;
  }

  public void run() {
    System.out.println("SingletonDoubleCheck::run() " + this.name);
  }
}

測試調(diào)用

    /**
     * 單例模式就是一個(gè)類只創(chuàng)建一個(gè)實(shí)例,以便節(jié)省開銷和保證統(tǒng)一
     * 對于多線程語言需要注意線程安全和性能之間取得一個(gè)平衡
     */
    SingletonEager singletonEager1 = SingletonEager.getInstance();
    SingletonEager singletonEager2 = SingletonEager.getInstance();
    singletonEager1.run();
    singletonEager2.run();
    // 兩個(gè)實(shí)例相等
    System.out.println("singletonEager1 == singletonEager2 ? " + String.valueOf(singletonEager1 == singletonEager2));

    /*********************** 分割線 ******************************************/

    SingletonLazy singletonLazy1 = SingletonLazy.getInstance("singletonLazy1");
    SingletonLazy singletonLazy2 = SingletonLazy.getInstance("singletonLazy2");
    singletonLazy1.run();
    singletonLazy2.run();

    /*********************** 分割線 ******************************************/

    SingletonDoubleCheck singletonDoubleCheck1 = SingletonDoubleCheck.getInstance("singletonDoubleCheck1");
    SingletonDoubleCheck singletonDoubleCheck2 = SingletonDoubleCheck.getInstance("singletonDoubleCheck2");
    singletonDoubleCheck1.run();
    singletonDoubleCheck2.run();

    /*********************** 分割線 ******************************************/

    SingletonInner singletonInner1 = SingletonInner.getInstance("singletonInner1");
    SingletonInner singletonInner2 = SingletonInner.getInstance("singletonInner2");
    singletonInner1.run();
    singletonInner2.run();

Go代碼

// DoubleCheckSingleton.go
import (
  "fmt"
  "sync"
)

// 安全懶漢模式的升級版,通過sync的Mutex實(shí)現(xiàn)雙重檢驗(yàn)
type DoubleCheckSingleton struct {
  name string
}

func (s *DoubleCheckSingleton) Run() {
  fmt.Println("DoubleCheckSingleton::run()", s.name)
}

// 定義私有變量,用來保存實(shí)例
var doubleCheckSingletonInstance *DoubleCheckSingleton
var lock = &sync.Mutex{}

// 是懶漢模式安升級版,雙重檢查來來支持延遲實(shí)例化單例對象
func GetDoubleCheckSingletonInstance(name string) *DoubleCheckSingleton {
  // 未實(shí)例化才進(jìn)行加鎖
  if doubleCheckSingletonInstance == nil {
    lock.Lock()
    defer lock.Unlock()
    // 為了保險(xiǎn),鎖住之后再次檢查是否已實(shí)例化
    if doubleCheckSingletonInstance == nil {
      doubleCheckSingletonInstance = &DoubleCheckSingleton{}
      doubleCheckSingletonInstance.name = name
    }
  }

  return doubleCheckSingletonInstance
}

JS版本

// LazySingleton.js
export class LazySingleton {
  static instance
  constructor(alias) {
    this.alias = alias
  }

  // 懶漢模式,延遲實(shí)例化,請求實(shí)例時(shí)判斷,如果已經(jīng)實(shí)例化過就直接返回
  // js是單線程語言,無需考慮多線程問題
  static getInstance(alias) {
    if (this.instance === undefined) {
      this.instance = new LazySingleton(alias)
    }
    return this.instance
  }

  run() {
    console.log('LazySingleton::run()', this.alias)
  }
}

Python語言

# SingletonSafe.py
from threading import Lock, Thread


# 加鎖的基于元類的單例模式,基于元類type創(chuàng)建的加強(qiáng)版
class SingletonMeta(type):
    # 線程安全單例模式,適用python3
    _instances = {}

    _lock: Lock = Lock()

    def __call__(cls, *args, **kwargs):
        with cls._lock:
            if cls not in cls._instances:
                instance = super().__call__(*args, **kwargs)
                cls._instances[cls] = instance
        return cls._instances[cls]

# 繼承SingletonMeta就是單例
class SingletonSafe(metaclass=SingletonMeta):
    name: str = None

    def __init__(self, name: str) -> None:
        self.name = name

    def run(self):
        print('SingletonSafe::run()', self.name)

C語言

// lazy_singleton_safe.c
#include "func.h"
#include <pthread.h>

// 靜態(tài)指針,未被創(chuàng)建并分配內(nèi)存空間,指向唯一實(shí)例
static LazySingletonSafe *lazy_singleton_safe_instance = NULL;

void lazy_singleton_safe_run(LazySingletonSafe *singleton)
{
  printf("\r\n LazySingletonSafe::run() [name=%s value=%d]", singleton->name, singleton->value);
}

// 內(nèi)部私有實(shí)例化函數(shù),不公開
static LazySingletonSafe *new_lazy_singleton_safe(char *name)
{
  LazySingletonSafe *singleton = (LazySingletonSafe *)malloc(sizeof(LazySingletonSafe));
  strcpy(singleton->name, name);
  singleton->run = &lazy_singleton_safe_run;
  return singleton;
}

// 聲明鎖
pthread_mutex_t singleton_lock;

// 非線程安全懶漢模式,延遲初始化。多個(gè)線程同時(shí)調(diào)用函數(shù)時(shí), 可能會被初始化多次,存在線程不安全問題
LazySingletonSafe *get_lazy_singleton_safe_instance(char *name)
{
  printf("\r\n get_lazy_singleton_safe_instance() [name=%s]", name);
  if (pthread_mutex_init(&singleton_lock, NULL) != 0)
  {
    perror("error init mutext:");
  }

  // 通過加鎖來防止線程并發(fā)導(dǎo)致的不安全
  if (lazy_singleton_safe_instance == NULL)
  {
    printf("\r\n new instance [name=%s]", name);
    pthread_mutex_lock(&singleton_lock);
    lazy_singleton_safe_instance = new_lazy_singleton_safe(name);
    pthread_mutex_unlock(&singleton_lock);
  }
  return lazy_singleton_safe_instance;
}

更多語言版本

不同語言實(shí)現(xiàn)設(shè)計(jì)模式:https://github.com/microwind/design-pattern文章來源地址http://www.zghlxwxcb.cn/news/detail-426723.html

到了這里,關(guān)于【單例設(shè)計(jì)模式原理詳解】Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【模板方法設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    模板方法模式(Template Method Pattern)也叫模板模式,是一種行為型模式。它定義了一個(gè)抽象公開類,包含基本的算法骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變算法的結(jié)構(gòu),只是重定義該算法的某些特定步驟。不同的子類以不同的方式實(shí)現(xiàn)這些抽象方法

    2024年02月01日
    瀏覽(22)
  • 【迭代器設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    【迭代器設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    迭代器模式(Iterator Pattern),是一種結(jié)構(gòu)型設(shè)計(jì)模式。給數(shù)據(jù)對象構(gòu)建一套按順序訪問集合對象元素的方式,而不需要知道數(shù)據(jù)對象的底層表示。 迭代器模式是與集合共存的,我們只要實(shí)現(xiàn)一個(gè)集合,就需要同時(shí)提供這個(gè)集合的迭代器,就像Java中的Collection,List、Set、Map等

    2023年04月17日
    瀏覽(15)
  • 【備忘錄設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    【備忘錄設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    備忘錄模式(Memento Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式。這種模式就是在不破壞封裝的條件下,將一個(gè)對象的狀態(tài)捕捉(Capture)住,并放在外部存儲起來,從而可以在將來合適的時(shí)候把這個(gè)對象還原到存儲起來的狀態(tài)。備忘錄模式常常與命令模式和迭代子模式一同使用。 備忘錄模式

    2023年04月20日
    瀏覽(26)
  • 【中介者設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    【中介者設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    中介者模式(Mediator Pattern)是一種行為型模式。它限制對象之間的直接交互,它用一個(gè)中介對象來封裝一系列的動作,以讓對象之間進(jìn)行交流。中介者使各個(gè)對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。 當(dāng)一些對象和其他對象緊密

    2023年04月19日
    瀏覽(28)
  • 【訪問者設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    【訪問者設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    訪問者模式(Visitor Pattern)是一種行為型模式。它封裝一個(gè)訪問者類,把各元素類的操作集合起來,目的是將數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)操作分離。在不改變原有元素類數(shù)據(jù)結(jié)構(gòu)的前提下,改變了元素類的執(zhí)行算法。 當(dāng)某些較為穩(wěn)定的東西(數(shù)據(jù)結(jié)構(gòu)或算法),不想直接被改變但又想擴(kuò)

    2024年02月02日
    瀏覽(21)
  • 【觀察者設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    【觀察者設(shè)計(jì)模式詳解】C/Java/JS/Go/Python/TS不同語言實(shí)現(xiàn)

    觀察者模式(Observer Pattern)是一種行為型模式。它定義對象間的一種一對多的依賴關(guān)系,當(dāng)一個(gè)對象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對象都得到通知并被自動更新。 觀察者模式使用三個(gè)類Subject、Observer和Client。Subject對象帶有綁定觀察者到Client對象和從Client對象解綁觀察

    2023年04月21日
    瀏覽(24)
  • 【解釋器設(shè)計(jì)模式詳解】C/Java/Go/JS/TS/Python不同語言實(shí)現(xiàn)

    【解釋器設(shè)計(jì)模式詳解】C/Java/Go/JS/TS/Python不同語言實(shí)現(xiàn)

    解釋器模式(Interpreter Pattern)是一種行為型設(shè)計(jì)模式。這種模式實(shí)現(xiàn)了一個(gè)表達(dá)式接口,該接口解釋一個(gè)特定的上下文。這種模式常被用在 SQL 解析、符號處理引擎等。 解釋器模式常用于對簡單語言的編譯或分析實(shí)例中,為了掌握好它的結(jié)構(gòu)與實(shí)現(xiàn),必須先了解編譯原理中的

    2023年04月12日
    瀏覽(1388)
  • 03-JAVA設(shè)計(jì)模式-單例模式詳解

    03-JAVA設(shè)計(jì)模式-單例模式詳解

    單例模式(Singleton Pattern)是設(shè)計(jì)模式中的一種,它確保一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)來訪問該實(shí)例。這種設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。 單例模式的應(yīng)用場景十分廣泛,主要涉及需要頻繁使用某個(gè)對象而又不想重復(fù)創(chuàng)建的情況

    2024年04月13日
    瀏覽(30)
  • 【設(shè)計(jì)模式】23種設(shè)計(jì)模式——單例模式(原理講解+應(yīng)用場景介紹+案例介紹+Java代碼實(shí)現(xiàn))

    【設(shè)計(jì)模式】23種設(shè)計(jì)模式——單例模式(原理講解+應(yīng)用場景介紹+案例介紹+Java代碼實(shí)現(xiàn))

    介紹 所謂類的單例設(shè)計(jì)模式,就是采取一定的方法, 保證在整個(gè)的軟件系統(tǒng)中,對某個(gè)類只能存在一個(gè)對象實(shí)例 ,并且該類只提供一個(gè)取得其對象實(shí)例的方法(靜態(tài)方法)。 比如Hibernate的SessionFactory,它充當(dāng)數(shù)據(jù)存儲源的代理,并負(fù)責(zé)創(chuàng)建Session對象。SessionFactory并不是輕量

    2024年02月13日
    瀏覽(31)
  • Java設(shè)計(jì)模式之單例模式詳解--獨(dú)一無二的事物

    Java設(shè)計(jì)模式之單例模式詳解--獨(dú)一無二的事物

    本文主要講述 單例模式 ,文中使用通俗易懂的案例,使你更好的學(xué)習(xí)本章知識點(diǎn)并理解原理,做到有道無術(shù)。 單例模式是23種設(shè)計(jì)模式中 創(chuàng)建型模式 的一種,通過單例模式的方法創(chuàng)建的類在當(dāng)前進(jìn)程或者線程中只有一個(gè)實(shí)例。單例模式有兩種比較常見的實(shí)現(xiàn)方式: 餓漢式

    2024年02月07日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包