您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)python怎么實(shí)現(xiàn)線程安全的單例模式,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
單例模式是一種常見(jiàn)的設(shè)計(jì)模式,該模式的主要目的是確保某一個(gè)類(lèi)只有一個(gè)實(shí)例存在。當(dāng)你希望在整個(gè)系統(tǒng)中,某個(gè)類(lèi)只能出現(xiàn)一個(gè)實(shí)例時(shí),單例對(duì)象就能派上用場(chǎng)。
比如,服務(wù)器的配置信息寫(xiě)在一個(gè)文件中online.conf中,客戶端通過(guò)一個(gè) Config 的類(lèi)來(lái)讀取配置文件的內(nèi)容。如果在程序運(yùn)行期間,有很多地方都需要使用配置文件的內(nèi)容,那么每個(gè)調(diào)用配置文件的地方都會(huì)創(chuàng)建 Config的實(shí)例,這就導(dǎo)致系統(tǒng)中存在多個(gè)Config 的實(shí)例對(duì)象,在配置文件內(nèi)容很多的情況下,我們就浪費(fèi)了大量的內(nèi)存做了同樣的事。事實(shí)上,對(duì)于Config類(lèi)我們?cè)诔绦蜻\(yùn)行期間時(shí)只需要一個(gè)實(shí)例對(duì)象即可,這時(shí)單例模式就是最好的選擇。
python的模塊就是天然的單例模式,這里我們使用修飾器來(lái)實(shí)現(xiàn)單例模式,以下是代碼實(shí)現(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
代碼也很簡(jiǎn)單,將類(lèi)傳入單例修飾器中,如果該類(lèi)還未生成實(shí)例(instances中不存在該類(lèi)),那么就生成一個(gè)新的實(shí)例返回,并記錄在instances中。如果已經(jīng)instances中已經(jīng)存在該類(lèi),那么直接返回實(shí)例instances[cls]。
那么這段代碼是完美的嗎?答案是否定的,這段代碼不是線程安全的。要實(shí)現(xiàn)線程安全需要配合鎖的使用,只有占有鎖的線程才能繼續(xù)訪問(wèn)單例實(shí)例,看來(lái)我們需要再寫(xiě)一個(gè)修飾器來(lái)實(shí)現(xiàn)線程安全了,以下是完整的代碼實(shí)現(xiàn)和簡(jiǎn)單的多線程測(cè)試用例。
#!/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()
關(guān)于“python怎么實(shí)現(xiàn)線程安全的單例模式”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。