Java設(shè)計(jì)模式之單件模式深入講解
定義
單件模式確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)
Java單件模式
經(jīng)典單件模式的實(shí)現(xiàn)
public class Singleton{
private static Singleton uniqueInstance; // 利用一個(gè)靜態(tài)變量來記錄Singleton類的唯一實(shí)例
private Singleton(){} // 把構(gòu)造器聲明為私有的,只有自Singleton類內(nèi)才可以調(diào)用構(gòu)造器
// 用getInstance()方法實(shí)例化對(duì)象,并返回這個(gè)實(shí)例
public static Singleton getInstance(){
if (uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
在多線程中以上代碼會(huì)生成多個(gè)實(shí)例,所以需要我們對(duì)代碼進(jìn)行改進(jìn)
多線程單件模式的實(shí)現(xiàn)
public class Singleton{
private static Singleton uniqueInstance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
通過增加synchronized關(guān)鍵字到getInstance()方法中,我們迫使每個(gè)線程在進(jìn)入這個(gè)方法之前,要先等候別的線程離開該方法。也就是說,不會(huì)有兩個(gè)線程可以同時(shí)進(jìn)入這個(gè)方法。
急切創(chuàng)建實(shí)例
public class Singleton{
// 在靜態(tài)初始化器(static initializai)中創(chuàng)建單件。這樣可以保證線程安全(thread sate)
private static Singleton uniqueInstance = new Singleton();
private static Singleton getInstance(){
return uniqueInstance;
}
}
在JVM在加載這個(gè)類時(shí)馬上創(chuàng)建此唯一的單件實(shí)例。JVM保證在任何線程訪問uniqueInstance靜態(tài)變量之前,一定創(chuàng)建此實(shí)例。
雙重檢查加鎖
會(huì)有兩次檢查實(shí)例是否存在,若不存在則創(chuàng)建實(shí)例,若存在則返回
public class Singlenton{
// volatile關(guān)鍵詞:當(dāng)uniqueInstance變量被初始化成Singleton實(shí)例時(shí),多個(gè)線程正確地處理uniqueInstance變量
private volatile static Singleton uniqueInstance();
private Singleton(){}
public static Singleton getInstance(){
// 檢查實(shí)例,如果不存在,就進(jìn)入同步區(qū)塊
if(uniqueInstance == null){
// 進(jìn)入?yún)^(qū)塊后,再檢查一次。如果仍是null,才創(chuàng)建實(shí)例
synchronized (Singleton.class){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
Python單件模式
模塊實(shí)現(xiàn)
Python 的模塊就是天然的單件模式,在模塊第一次被導(dǎo)入時(shí),會(huì)生成.pyc文件,之后再次導(dǎo)入時(shí),就會(huì)直接加載之前生成的.pyc文件,不會(huì)再次執(zhí)行模塊代碼
先創(chuàng)建一個(gè)Singleton文件
class Singleton: def getSingleton: pass singleton = Singleton()
在其他文件中導(dǎo)入這個(gè)模塊,這個(gè)類的地址是唯一的
new關(guān)鍵字實(shí)現(xiàn)
當(dāng)實(shí)例化一個(gè)對(duì)象時(shí),先調(diào)用類的__new__方法 ,默認(rèn)調(diào)用的是父類Object.__new__方法,實(shí)例化對(duì)象。然后再調(diào)用類的__init__方法進(jìn)行屬性的初始化。
我們可以再__new__方法內(nèi)加一個(gè)判斷,若實(shí)例存在,則不實(shí)例化,若不存在,則實(shí)例化。
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
def __init__(self):
pass
裝飾器實(shí)現(xiàn)
通過裝飾器來實(shí)現(xiàn)單件模式
函數(shù)裝飾器
def singleton(cls):
# 創(chuàng)建一個(gè)私有變量,類型為字典,用來存放類地址的
_instance = {}
def inner():
# 如果類不存在
if cls not in _instance:
# 實(shí)例化一個(gè)類并存放在字典里
_instance[cls] = cls()
return _instance[cls]
return inner
@singleton
class ClassName(object):
def __init__(self):
pass
類裝飾器
class Singleton(object):
def __init__(self, cls):
self._cls = cls # 接受類名
self._instance = {} # 存放類地址
def __call__(self):
if self._cls not in self._instance:
# 實(shí)例化類并存放在字典內(nèi)
self._instance[self._cls] = self._cls()
return self._instance[self._cls]
@Singleton
class ClassName(object):
def __init__(self):
pass
以上就是Java設(shè)計(jì)模式之單件模式深入講解的詳細(xì)內(nèi)容,更多關(guān)于Java設(shè)計(jì)模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Boot文件上傳原理與實(shí)現(xiàn)詳解
這篇文章主要介紹了Spring Boot 文件上傳原理與實(shí)現(xiàn)詳解,前端文件上傳是面向多用戶的,多用戶之間可能存在上傳同一個(gè)名稱、類型的文件;為了避免文件沖突導(dǎo)致的覆蓋問題這些應(yīng)該在后臺(tái)進(jìn)行解決,需要的朋友可以參考下2024-01-01
java并發(fā)編程JUC CountDownLatch線程同步
這篇文章主要介紹CountDownLatch是什么、CountDownLatch 如何工作、CountDownLatch 的代碼例子來展開對(duì)java并發(fā)編程JUC CountDownLatch線程同步,需要的朋友可以參考下面文章內(nèi)容2021-09-09
Java實(shí)戰(zhàn)之酒店人事管理系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了如何用Java實(shí)現(xiàn)酒店人事管理系統(tǒng),文中采用的技術(shù)有:JSP、Spring、SpringMVC、MyBatis等,感興趣的小伙伴可以學(xué)習(xí)一下2022-03-03
SpringBoot動(dòng)態(tài)生成接口實(shí)現(xiàn)流程示例講解
最近遇到一個(gè)需求,需要在程序運(yùn)行過程中,可以動(dòng)態(tài)新增接口,自定義接口參數(shù)名稱,基本類型,以及請(qǐng)求方法,請(qǐng)求頭等等。通過幾天的研究,找到了我需要的解決方案2023-01-01
SpringBoot集成Redisson操作Redis的實(shí)現(xiàn)方法
Redisson是一個(gè)用于Java的Redis客戶端,它提供了在分布式環(huán)境下操作Redis數(shù)據(jù)庫的簡單、高效的方式,本文主要介紹了SpringBoot集成Redisson操作Redis的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
springboot2.x使用Jsoup防XSS攻擊的實(shí)現(xiàn)
這篇文章主要介紹了springboot2.x使用Jsoup防XSS攻擊的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Java中g(shù)etResourceAsStream用法分析
這篇文章主要介紹了Java中g(shù)etResourceAsStream用法,較為詳細(xì)的分析了getResourceAsStream的功能及用法,需要的朋友可以參考下2015-06-06

