详解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提取字典key列表的方法
Jul 11 Python
使用Python+Splinter自动刷新抢12306火车票
Jan 03 Python
python中字符串变二维数组的实例讲解
Apr 03 Python
详解pyqt5 动画在QThread线程中无法运行问题
May 05 Python
解决python xx.py文件点击完之后一闪而过的问题
Jun 24 Python
Python实现Mysql数据统计及numpy统计函数
Jul 15 Python
Python中的With语句的使用及原理
Jul 29 Python
python+django+selenium搭建简易自动化测试
Aug 19 Python
python 读取、写入txt文件的示例
Sep 27 Python
python 利用Pyinstaller打包Web项目
Oct 23 Python
Anaconda详细安装步骤图文教程
Nov 12 Python
详解Python小数据池和代码块缓存机制
Apr 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 GD 图像处理组件的常用函数总结
2010/04/28 PHP
php缩小png图片不损失透明色的解决方法
2013/12/25 PHP
浅谈php优化需要注意的地方
2014/11/27 PHP
php支付宝在线支付接口开发教程
2016/09/19 PHP
PHP堆栈调试操作简单示例
2018/06/15 PHP
textarea中的手动换行处理的jquery代码
2011/02/26 Javascript
JS+HTML5手机开发之滚动和惯性缓动实现方法分析
2016/06/12 Javascript
javascript内存分配原理实例分析
2017/04/10 Javascript
NodeJs中express框架的send()方法简介
2017/06/20 NodeJs
自定义事件解决重复请求BUG的问题
2017/07/11 Javascript
react-native 封装选择弹出框示例(试用ios&android)
2017/07/11 Javascript
vue读取本地的excel文件并显示在网页上方法示例
2019/05/29 Javascript
Object.keys() 和 Object.getOwnPropertyNames() 的区别详解
2020/05/21 Javascript
跟老齐学Python之Python文档
2014/10/10 Python
python实现的DES加密算法和3DES加密算法实例
2015/06/03 Python
python的文件操作方法汇总
2017/11/10 Python
Django实现学生管理系统
2019/02/26 Python
python按修改时间顺序排列文件的实例代码
2019/07/25 Python
Python字符编码转码之GBK,UTF8互转
2020/02/09 Python
Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解
2020/02/18 Python
Pyspark读取parquet数据过程解析
2020/03/27 Python
Python 捕获代码中所有异常的方法
2020/08/03 Python
HTML5 canvas基本绘图之填充样式实现
2016/06/27 HTML / CSS
白兰氏健康Mall:BRAND’S
2017/11/13 全球购物
女士和男士时尚鞋在线购物:Shoespie
2019/02/28 全球购物
日本最佳原创设计品牌:Felissimo(芬理希梦)
2019/03/19 全球购物
外贸英语专业求职信范文
2013/12/25 职场文书
试用期员工考核制度
2014/01/22 职场文书
农村面貌改造提升实施方案
2014/03/18 职场文书
采购意向书范本
2014/03/31 职场文书
车贷收入证明范本
2014/09/14 职场文书
党员个人剖析材料(四风问题)
2014/10/07 职场文书
单位法人授权委托书范本
2014/10/09 职场文书
个人政风行风自查自纠报告
2014/10/21 职场文书
vue实现无缝轮播效果(跑马灯)
2021/05/14 Vue.js
Python机器学习之基础概述
2021/05/19 Python