python中的單例可以利用__new__和__init__來實現。每次建立例項的時候總會獲得同乙個例項,但是每次也會執行__init__方法。這就會造成單例中的屬性會被修改,更重要的是例項會被重新初始化。有時候我們並不希望再次初始化例項,我們希望直接獲得已經建立好的例項。應用類變數和鎖機制,可以實現需求。
import threading
from concurrent.futures.thread import threadpoolexecutor
class singleton:
_instance = none
def __new__(cls, *args, **kwargs):
if cls._instance is none:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, num):
self.num = num
self.__init_flag = true
def get_name(self):
return self.num
def run_job(num):
obj = singleton(num)
print("thread:%s id:%s num:%s" % (num, id(obj), obj.num))
with threadpoolexecutor(max_workers=5) as pool:
for line in range(10):
pool.submit(run_job, line)
上面樣例的執行結果為。
thread:0 id:43341256 num:0從結果中看到執行的10個執行緒中所建立的例項是同乙個,因為例項的 id 是相同的,所以例項物件所指的記憶體位址是同乙個,是同乙個例項。但是它們的屬性 num 是不同的,這是因為雖然例項是同乙個,記憶體位址也是乙個,但是每個例項都初始化了一遍(執行了一遍 __init__ 方法),初始化的時候對例項的屬性 num 值進行了覆蓋。thread:1 id:43341256 num:1
thread:2 id:43341256 num:2
thread:3 id:43341256 num:3
thread:4 id:43341256 num:4
thread:5 id:43341256 num:5thread:6 id:43341256 num:6
thread:7 id:43341256 num:7
thread:8 id:43341256 num:8
thread:9 id:43341256 num:9
它們確確實實是同乙個例項,但是屬性值卻發生了改變。這就像是「乙個人」作為乙個例項,而這個人改了名字,本來叫「小小」,後來改名叫「大大」,不管叫啥他都是同乙個人。
有些時候我們建立乙個單例後並不想讓它修改屬性。我們想第一次建立例項完成後,第二次建立的時候直接返回單例,不要在去執行初始化方法,避免多次初始化帶來的資源和時間開銷。樣例**如下所示。
import threading
from concurrent.futures.thread import threadpoolexecutor
class singleton:
_lock_1 = threading.lock()
_lock_2 = threading.lock()
_instance = none
__init_flag = false
def __new__(cls, *args, **kwargs):
if cls._instance:
return cls._instance
with cls._lock_1:
if cls._instance is none:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, num):
if self.__init_flag:
return
with self._lock_2:
if self.__init_flag:
return
self.num = num
self.__init_flag = true
def get_name(self):
return self.num
def run_job(num):
obj = singleton(num)
print("thread:%s id:%s num:%s" % (num, id(obj), obj.num))
with threadpoolexecutor(max_workers=10) as pool:
for line in range(50):
pool.submit(run_job, line)
# task =
# for i in range(10):
# t = threading.thread(target=run_job, args=(i,))
## for one in task:
# one.start()
## for one in task:
# one.join()
執行結果為。
thread:0 id:43669064 num:0thread:1 id:43669064 num:0
thread:2 id:43669064 num:0
thread:3 id:43669064 num:0
thread:4 id:43669064 num:0
thread:5 id:43669064 num:0
thread:6 id:43669064 num:0
thread:7 id:43669064 num:0thread:8 id:43669064 num:0
thread:9 id:43669064 num:0
陣列 初始化 只含動態初始化 靜態初始化
首先j a中此處只講靜態初始化 動態初始化 靜態初始化就是提前在陣列中設定好了陣列內容,此內容不做改動,該多長已經在設定內容的時候已經決定 動態初始化就是僅限於new及確定陣列大小長度,裡面的陣列內容沒有,可自由進行填寫,也包含了靜態初始化的內容 示例 package 陣列 public class...
易語言多執行緒大漠多執行緒模板多執行緒初始化
多執行緒初始化,在啟動視窗後,需要首先呼叫,包括對執行緒控制代碼,視窗控制代碼,程序pid,程序狀態,異常狀態,是否暫停,是否結束的初始化,特別說明的是,為任務狀態申請記憶體空間,因為任務狀態的資料型別是文字型,防止避免多執行緒訪問文字型變數引發的資料衝突,預先分配好記憶體位址。511遇見易語言多執...
Python單例模式並且保證只被初始化一次
單例模式 假設我們有乙個日誌記錄器的類,現在我們不希望在每乙個需要寫入日誌的地方生成乙個日誌記錄器,那麼我們的做法是 如果已經在程式中存在乙個日誌記錄器,那麼就獲取它 如果不存在,則新建立乙個日誌記錄器。並且我們想保證 init 方法只執行一次 class singletonclass instan...