詳解python實現(xiàn)線程安全的單例模式
單例模式是一種常見的設(shè)計模式,該模式的主要目的是確保某一個類只有一個實例存在。當(dāng)你希望在整個系統(tǒng)中,某個類只能出現(xiàn)一個實例時,單例對象就能派上用場。
比如,服務(wù)器的配置信息寫在一個文件中online.conf中,客戶端通過一個 Config 的類來讀取配置文件的內(nèi)容。如果在程序運(yùn)行期間,有很多地方都需要使用配置文件的內(nèi)容,那么每個調(diào)用配置文件的地方都會創(chuàng)建 Config的實例,這就導(dǎo)致系統(tǒng)中存在多個Config 的實例對象,在配置文件內(nèi)容很多的情況下,我們就浪費(fèi)了大量的內(nèi)存做了同樣的事。事實上,對于Config類我們在程序運(yùn)行期間時只需要一個實例對象即可,這時單例模式就是最好的選擇。
python的模塊就是天然的單例模式,這里我們使用修飾器來實現(xiàn)單例模式,以下是代碼實現(xiàn)
def Singleton(cls):
instances = {}
def get_instance(*args, **kw):
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return get_instance
代碼也很簡單,將類傳入單例修飾器中,如果該類還未生成實例(instances中不存在該類),那么就生成一個新的實例返回,并記錄在instances中。如果已經(jīng)instances中已經(jīng)存在該類,那么直接返回實例instances[cls]。
那么這段代碼是完美的嗎?答案是否定的,這段代碼不是線程安全的。要實現(xiàn)線程安全需要配合鎖的使用,只有占有鎖的線程才能繼續(xù)訪問單例實例,看來我們需要再寫一個修飾器來實現(xiàn)線程安全了,以下是完整的代碼實現(xiàn)和簡單的多線程測試用例。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import threading
def synchronized(func):
func.__lock__ = threading.Lock()
def synced_func(*args, **kws):
with func.__lock__:
return func(*args, **kws)
return synced_func
def Singleton(cls):
instances = {}
@synchronized
def get_instance(*args, **kw):
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return get_instance
def worker():
single_test = test()
print "id----> %s" % id(single_test)
@Singleton
class test():
a = 1
if __name__ == "__main__":
task_list = []
for one in range(30):
t = threading.Thread(target=worker)
task_list.append(t)
for one in task_list:
one.start()
for one in task_list:
one.join()
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于Python實現(xiàn)Excel轉(zhuǎn)Markdown表格
Markdown(也簡稱md)作為一種輕量級標(biāo)記語言,因其易寫易讀,效果美觀大方,不僅被眾多網(wǎng)站使用,也是程序員們做筆記、寫文檔的首選。本文將利用Python實現(xiàn)Excel轉(zhuǎn)Markdown表格,感興趣的可以了解一下2022-04-04
Python解決ModuleNotFoundError: No module named&
ModuleNotFoundError: No module named 'PIL'是一個常見的Python錯誤,通常出現(xiàn)在使用Pillow庫時,Pillow是Python中用于圖像處理的一個庫,其前身是PIL,本文介紹了Python解決ModuleNotFoundError: No module named 'PIL'的問題,需要的朋友可以參考下2024-09-09
Python實現(xiàn)學(xué)生信息管理系統(tǒng)的示例代碼
夏天是用來告別的季節(jié),因為畢業(yè)總在七月。那么七月之前的季節(jié)是用來干嘛的呢?當(dāng)然是用來做畢業(yè)設(shè)計的啦!本文為大家準(zhǔn)備了兩個版本的學(xué)生信息管理系統(tǒng),希望對大家有所幫助2023-02-02
深入分析在Python模塊頂層運(yùn)行的代碼引起的一個Bug
幾個星期前, 我的同事跑過來, 說發(fā)現(xiàn)一個奇怪的Bug: 在使用Python的subprocess運(yùn)行子進(jìn)程時, 當(dāng)子進(jìn)程運(yùn)行失敗時居然沒有拋出錯誤!2014-07-07
pandas pivot_table() 按日期分多列數(shù)據(jù)的方法
今天小編就為大家分享一篇pandas pivot_table() 按日期分多列數(shù)據(jù)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11

