详解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将图片文件转换成base64编码的方法
Mar 14 Python
python实现bucket排序算法实例分析
May 04 Python
在Django的视图中使用数据库查询的方法
Jul 16 Python
python正则表达式的使用
Jun 12 Python
python spyder中读取txt为图片的方法
Apr 27 Python
python pandas读取csv后,获取列标签的方法
Nov 12 Python
Python3enumrate和range对比及示例详解
Jul 13 Python
Python-opencv 双线性插值实例
Jan 17 Python
如何利用python之wxpy模块玩转微信
Aug 17 Python
Python3中的tuple函数知识点讲解
Jan 03 Python
conda安装tensorflow和conda常用命令小结
Feb 20 Python
python中if嵌套命令实例讲解
Feb 25 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设计模式 Facade(外观模式)
2011/06/26 PHP
Yii框架视图、视图布局、视图数据块操作示例
2019/10/14 PHP
简单的JS多重继承示例
2008/03/13 Javascript
JQuery 选择器 xpath 语法应用
2010/05/13 Javascript
ExtJS 下拉多选框lovcombo
2010/05/19 Javascript
Jquery跨域获得Json时invalid label错误的解决办法
2011/01/11 Javascript
原生js实现查找/添加/删除/指定元素的class
2013/04/12 Javascript
js 显示base64编码的二进制流网页图片
2014/04/04 Javascript
jQuery不使用插件及swf实现无刷新文件上传
2014/12/08 Javascript
轻松创建nodejs服务器(5):事件处理程序
2014/12/18 NodeJs
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
js带点自动图片轮播幻灯片特效代码分享
2015/09/07 Javascript
JavaScript中的this,call,apply使用及区别详解
2016/01/29 Javascript
详解Node.js包的工程目录与NPM包管理器的使用
2016/02/16 Javascript
bootstrap multiselect 多选功能实现方法
2017/06/05 Javascript
利用js将ajax获取到的后台数据动态加载至网页中的方法
2018/08/08 Javascript
vue表单自定义校验规则介绍
2018/08/28 Javascript
bootstrapTable+ajax加载数据 refresh更新数据
2018/08/31 Javascript
vue服务端渲染添加缓存的方法
2018/09/18 Javascript
js 实现碰撞检测的示例
2020/10/28 Javascript
关于Js中new操作符的作用详解
2021/02/21 Javascript
[03:17]DOTA2-DPC中国联赛1月29日Recap集锦
2021/03/11 DOTA
在Python中使用pngquant压缩png图片的教程
2015/04/09 Python
Python程序中用csv模块来操作csv文件的基本使用教程
2016/03/03 Python
python爬取NUS-WIDE数据库图片
2016/10/05 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
python生成每日报表数据(Excel)并邮件发送的实例
2019/02/03 Python
Python基础之条件控制操作示例【if语句】
2019/03/23 Python
python 使用matplotlib 实现从文件中读取x,y坐标的可视化方法
2019/07/04 Python
Django配置MySQL数据库的完整步骤
2019/09/07 Python
Python 中的 import 机制之实现远程导入模块
2019/10/29 Python
Python3如何使用多线程升程序运行速度
2020/08/11 Python
Django Form常用功能及代码示例
2020/10/13 Python
华为慧通笔试题
2016/04/22 面试题
简述使用ftp进行文件传输时的两种登录方式?它们的区别是什么?常用的ftp文件传输命令是什么?
2016/11/20 面试题
星空联盟C# .net笔试题
2014/12/05 面试题