Singleton 模式,中文既为 单实例模式 。
一、代码示例
看一下普通的类:
class Normal(object):
_instance = []
config = ''
def set(self,value):
self.config = value
def get(self):
return self.confg
if __name__ == '__main__':
s1 = Normal()
s1.set('s1')
s2 = Normal()
s2.set('s2')
print id(s1)
print id(s2)
print s1.get()
print s2.get()
运行结果 :
ubuntu@yee:/tmp$ python t.py
139782948272976
139782948273040
s1
s2
可以看到,代码中生成了两个实例,每个实例都拥有自己的内存空间。
接下来看单实例的代码示例:
class Singleton(object):
_instance = []
config = ''
def __new__(cls,*args,**kwargs):
if not cls._instance:
cls._instance = super(Singleton,cls).__new__(cls,*args,**kwargs)
return cls._instance
def set(self,value):
self.config = value
def get(self):
return self.config
if __name__ == '__main__':
s1 = Singleton()
s1.set('config:s1')
s2 = Singleton()
s2.set('config:s2')
print id(s1)
print id(s2)
print s1.get()
print s2.get()
ubuntu@yee:/tmp$ python t.py
<__main__.Singleton object at 0x7f948b034c10>
<__main__.Singleton object at 0x7f948b034c10>
140275964136464
140275964136464
config:s2
config:s2
看到s2和s1 是同一个实例,所使用的都是同一个内存空间,所以 s1.set() 和s2.set()是设置了同一个变量 。
但是以上的代码也会有一个问题:线程安全
如果并发运行了两个线程,都检测到当前的 cls._instance = null ,那么都会创建新的线程,此时就全乱了。所以,我们需要加锁
#!/usr/bin/python
#-*- coding:utf8 -*-
import threading
import time
class Singleton(object):
_instance = []
config = ''
def __new__(cls,*args,**kwargs):
if not cls._instance:
print "I will lock thread"
mlock = threading.Lock()
mlock.acquire()
cls._instance = super(Singleton,cls).__new__(cls,*args,**kwargs)
mlock.release()
return cls._instance
def set(self,value):
self.config = value
def get(self):
return self.config
def execute():
s1 = Singleton()
print str(id(s1)) + "\n"
if __name__ == '__main__':
thread1 = threading.Thread(target=execute)
thread2 = threading.Thread(target=execute)
thread1.start()
thread2.start()
只有第一次创建实例的时候才会加锁,所以不用担心会影响性能 。
搞清楚了上面的代码之后,就可以总结出单实例的优点了:
节省内存空间
二、单实例的使用场景 :
比方说,
OS在开机之后,会维护一份用户的配置文件,这份文件 从开机到关机期间只需要有一份,并且常驻内存之中。这个时间就需要使用单实例。
单实例可以使系统不必在用户去修改某一项配置的时候重新new一个实例,单实例对象是全局的,常驻内存的,所以只需要直接赋值就可以了。
三、为什么需要避免使用单实例
请自行google : why singleton bad
(使用百度的程序猿不是好程序猿)
http://www.cnblogs.com/vwxyzh/archive/2010/07/17/1779620.html
http://www.btsmth.com/show_topic.php?en_name=SoftEng&gid=81604
来源:oschina
链接:https://my.oschina.net/u/1043170/blog/136046