File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 66## \_\_ new__ ()实现单例
77``` python
88class Singleton :
9+
910 def __new__ (cls , * args , ** kwargs ):
1011 if not hasattr (cls , ' instance' ):
1112 cls .instance = super ().__new__ (cls )
1213 return cls .instance
1314
14-
1515if __name__ == ' __main__' :
1616 s1 = Singleton()
1717 s2 = Singleton()
18- print (s1 is s2) # True
18+ print (' s1:{} ' .format(id (s1)))
19+ print (' s2:{} ' .format(id (s2)))
20+ print (' s1 is s2:{} ' .format(s1 is s2))
21+ ```
22+ ``` python
23+ s1:1891632871352
24+ s2:1891632871352
25+ s1 is s2:True
26+ ```
27+
28+ ** 以上看似实现了单例模式,但实际在多线程的情况下会有问题,多个线程同时创建单例对象,如果不加锁的情况下是不安全的。**
29+
30+ ``` python
31+ import time
32+ import threading
33+
34+ class Singleton :
35+
36+ def __new__ (cls , * args , ** kwargs ):
37+ if not hasattr (cls , ' instance' ):
38+ time.sleep(0.05 )
39+ cls .instance = super ().__new__ (cls )
40+ return cls .instance
41+
42+ def func ():
43+ s = Singleton()
44+ print (' s:{} ' .format(id (s)))
45+
46+ if __name__ == ' __main__' :
47+ for _ in range (5 ):
48+ # 开启5个线程同时创建对象
49+ td = threading.Thread(target = func)
50+ td.start()
51+ ```
52+ ``` python
53+ s:1230297165896
54+ s:1230297245008
55+ s:1230297372152
56+ s:1230297270648
57+ s:1230297296176
58+ ```
59+
60+ ** 多线程先创建单例对象需要加锁**
61+
62+ ``` python
63+ import threading
64+
65+ class Singleton :
66+ _instance_lock = threading.Lock()
67+
68+ def __new__ (cls , * args , ** kwargs ):
69+ # 加锁
70+ with cls ._instance_lock:
71+ if not hasattr (cls , ' instance' ):
72+ cls .instance = super ().__new__ (cls )
73+ return cls .instance
74+
75+ def func ():
76+ s = Singleton()
77+ print (' s:{} ' .format(id (s)))
78+
79+ if __name__ == ' __main__' :
80+ for _ in range (5 ):
81+ td = threading.Thread(target = func)
82+ td.start()
1983```
You can’t perform that action at this time.
0 commit comments