详解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 struct.unpack
Sep 06 Python
Python文件操作类操作实例详解
Jul 11 Python
Python获取文件ssdeep值的方法
Oct 05 Python
python分析nignx访问日志脚本分享
Feb 26 Python
Python内置的HTTP协议服务器SimpleHTTPServer使用指南
Mar 30 Python
python字符串str和字节数组相互转化方法
Mar 18 Python
用python实现百度翻译的示例代码
Mar 09 Python
Python实现直方图均衡基本原理解析
Aug 08 Python
在Python中获取操作系统的进程信息
Aug 27 Python
pytorch1.0中torch.nn.Conv2d用法详解
Jan 10 Python
Python 利用OpenCV给照片换底色的示例代码
Aug 03 Python
如何利用python生成MD5并去重
Dec 07 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
用PHP实现的生成静态HTML速度快类库
2007/03/31 PHP
Yii把CGridView文本框换成下拉框的方法
2014/12/03 PHP
PHP验证码无法显示的原因及解决办法
2017/08/11 PHP
JavaScript 学习笔记(十二) dom
2010/01/21 Javascript
基于jquery实现拆分姓名的方法(纯JS版)
2013/05/08 Javascript
jQuery学习之prop和attr的区别示例介绍
2013/11/15 Javascript
js操作输入框提示信息且响应鼠标事件
2014/03/25 Javascript
javascript三元运算符用法实例
2015/04/16 Javascript
javascript实现行拖动的方法
2015/05/27 Javascript
常用原生JS兼容性写法汇总
2016/04/27 Javascript
jQuery通过ajax方法获取json数据不执行success的原因及解决方法
2016/10/15 Javascript
validationEngine 表单验证插件使用实例代码
2017/06/15 Javascript
Bootstrap模态对话框用法简单示例
2018/08/31 Javascript
VUE接入腾讯验证码功能(滑块验证)备忘
2019/05/07 Javascript
VUE前后端学习tab写法实例
2019/08/06 Javascript
微信小程序批量监听输入框对按钮样式进行控制的实现代码
2019/10/12 Javascript
Python  连接字符串(join %)
2008/09/06 Python
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
Python实现手机号自动判断男女性别(实例解析)
2019/12/22 Python
通过实例解析Python return运行原理
2020/03/04 Python
parser.add_argument中的action使用
2020/04/20 Python
基于opencv的selenium滑动验证码的实现
2020/07/24 Python
Python环境使用OpenCV检测人脸实现教程
2020/10/19 Python
一款纯css3实现的非常实用的鼠标悬停特效演示
2014/11/05 HTML / CSS
使用css3实现的windows8开机加载动画
2014/12/09 HTML / CSS
详解CSS3的opacity属性设置透明效果的用法
2016/05/09 HTML / CSS
Jo Malone美国官网:祖玛珑香水
2017/03/27 全球购物
Nice Kicks网上商店:ShopNiceKicks.com
2018/12/25 全球购物
Mansur Gavriel官网:纽约市的一个设计品牌
2019/05/02 全球购物
植树节活动总结
2014/04/30 职场文书
技术比武方案
2014/05/19 职场文书
酒店管理毕业生自荐信
2014/05/25 职场文书
大学生社会实践活动总结
2014/07/03 职场文书
干部考察材料范文
2014/12/24 职场文书
2016幼儿教师自荐信范文
2016/01/28 职场文书
导游词之徐州-云龙山
2019/09/29 职场文书