详解python实现线程安全的单例模式


Posted in Python onMarch 05, 2018

单例模式是一种常见的设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,服务器的配置信息写在一个文件中online.conf中,客户端通过一个 Config 的类来读取配置文件的内容。如果在程序运行期间,有很多地方都需要使用配置文件的内容,那么每个调用配置文件的地方都会创建 Config的实例,这就导致系统中存在多个Config 的实例对象,在配置文件内容很多的情况下,我们就浪费了大量的内存做了同样的事。事实上,对于Config类我们在程序运行期间时只需要一个实例对象即可,这时单例模式就是最好的选择。

python的模块就是天然的单例模式,这里我们使用修饰器来实现单例模式,以下是代码实现

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中。如果已经instances中已经存在该类,那么直接返回实例instances[cls]。

那么这段代码是完美的吗?答案是否定的,这段代码不是线程安全的。要实现线程安全需要配合锁的使用,只有占有锁的线程才能继续访问单例实例,看来我们需要再写一个修饰器来实现线程安全了,以下是完整的代码实现和简单的多线程测试用例。

#!/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()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python的MongoDB模块PyMongo操作方法集锦
Jan 05 Python
Python使用poplib模块和smtplib模块收发电子邮件的教程
Jul 02 Python
详解python中requirements.txt的一切
Mar 03 Python
Python 专题二 条件语句和循环语句的基础知识
Mar 19 Python
Python 专题三 字符串的基础知识
Mar 19 Python
python添加模块搜索路径方法
Sep 11 Python
python 对多个csv文件分别进行处理的方法
Jan 07 Python
关于numpy中eye和identity的区别详解
Nov 29 Python
python Tensor和Array对比分析
Jan 08 Python
python + selenium 刷B站播放量的实例代码
Jun 12 Python
Python使用xpath实现图片爬取
Sep 16 Python
python中os.path.join()函数实例用法
May 26 Python
分析python动态规划的递归、非递归实现
Mar 04 #Python
python3.x上post发送json数据
Mar 04 #Python
python数据封装json格式数据
Mar 04 #Python
Python爬虫实例扒取2345天气预报
Mar 04 #Python
Python爬虫设置代理IP的方法(爬虫技巧)
Mar 04 #Python
浅析python实现scrapy定时执行爬虫
Mar 04 #Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
Mar 04 #Python
You might like
BBS(php & mysql)完整版(五)
2006/10/09 PHP
探讨PHP使用eAccelerator的API开发详解
2013/06/09 PHP
Dojo 学习要点
2010/09/03 Javascript
jq实现酷炫的鼠标经过图片翻滚效果
2014/03/12 Javascript
JS+CSS实现仿支付宝菜单选中效果代码
2015/09/25 Javascript
基于Jquery和html5实现炫酷的3D焦点图动画
2016/03/02 Javascript
详解本地Node.js服务器作为api服务器的解决办法
2017/02/28 Javascript
Bootstrap栅格系统使用方法及页面调整变形的解决方法
2017/03/10 Javascript
BootStrap注意事项小结(五)表单
2017/03/10 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
2017/08/03 Javascript
webpack dll打包重复问题优化的解决
2018/10/10 Javascript
使用p5.js临摹动态图片
2019/11/04 Javascript
[01:59]游戏“zheng”当时试玩会
2019/08/21 DOTA
[01:03:50]DOTA2-DPC中国联赛 正赛 CDEC vs DLG BO3 第二场 2月7日
2021/03/11 DOTA
python实现图像识别功能
2018/01/29 Python
TensorFlow神经网络优化策略学习
2018/03/09 Python
Python数据处理numpy.median的实例讲解
2018/04/02 Python
对python中的logger模块全面讲解
2018/04/28 Python
Python字符串逆序输出的实例讲解
2019/02/16 Python
Pandas_cum累积计算和rolling滚动计算的用法详解
2019/07/04 Python
用python3 返回鼠标位置的实现方法(带界面)
2019/07/05 Python
python3.6+selenium实现操作Frame中的页面元素
2019/07/16 Python
解决TensorFlow GPU版出现OOM错误的问题
2020/02/03 Python
如何使用Python抓取网页tag操作
2020/02/14 Python
Python第三方库安装缓慢的解决方法
2021/02/06 Python
css3与html5实现响应式导航菜单(导航栏)效果分享
2014/02/12 HTML / CSS
师范生教师实习自我鉴定
2013/09/27 职场文书
大学生职业生涯规划书模板
2014/01/18 职场文书
我的中国梦口号
2014/06/16 职场文书
坚守艰苦奋斗精神坚决反对享乐主义整改措施
2014/09/17 职场文书
对领导班子的意见和建议
2015/06/08 职场文书
门球健将观后感
2015/06/16 职场文书
小学英语教学反思范文
2016/02/15 职场文书
2019年暑期法院实习报告
2019/12/18 职场文书
利用前端HTML+CSS+JS开发简单的TODOLIST功能(记事本)
2021/04/13 Javascript
Python字符串对齐方法使用(ljust()、rjust()和center())
2021/04/26 Python