详解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中使用socket发送HTTP请求数据接收不完整问题解决方法
Feb 04 Python
将Django框架和遗留的Web应用集成的方法
Jul 24 Python
解读Python编程中的命名空间与作用域
Oct 16 Python
详解Python中的相对导入和绝对导入
Jan 06 Python
python 爬虫出现403禁止访问错误详解
Mar 11 Python
Python实现的对本地host127.0.0.1主机进行扫描端口功能示例
Feb 15 Python
pandas DataFrame 交集并集补集的实现
Jun 24 Python
Python程序打包工具py2exe和PyInstaller详解
Jun 28 Python
python买卖股票的最佳时机(基于贪心/蛮力算法)
Jul 05 Python
基于python调用psutil模块过程解析
Dec 20 Python
Python实现发票自动校核微信机器人的方法
May 22 Python
详细总结Python常见的安全问题
May 21 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
实时抓取YAHOO股票报价的代码
2006/10/09 PHP
php checkdate、getdate等日期时间函数操作详解
2010/03/11 PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
2016/07/23 PHP
yii框架搜索分页modle写法
2016/12/19 PHP
jquery 页面全选框实践代码
2010/04/02 Javascript
JavaScript中数组继承的简单示例
2015/07/29 Javascript
正则表达式(语法篇推荐)
2016/06/24 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
2016/09/18 Javascript
JS调用打印机功能简单示例
2016/11/28 Javascript
详解VueRouter进阶之导航钩子和路由元信息
2017/09/13 Javascript
vue项目实现记住密码到cookie功能示例(附源码)
2018/01/31 Javascript
mpvue小程序仿qq左滑置顶删除组件
2018/08/03 Javascript
angularjs的单选框+ng-repeat的实现方法
2018/09/12 Javascript
vant 自定义 van-dropdown-item的用法
2020/08/05 Javascript
OpenLayers加载缩放控件使用方法详解
2020/09/25 Javascript
Javascript文本框脚本实现方法解析
2020/10/30 Javascript
Python学习资料
2007/02/08 Python
python对字典进行排序实例
2014/09/25 Python
python编写简单爬虫资料汇总
2016/03/22 Python
python 爬虫出现403禁止访问错误详解
2017/03/11 Python
python+mongodb数据抓取详细介绍
2017/10/25 Python
python 3.0 模拟用户登录功能并实现三次错误锁定
2017/11/01 Python
python MysqlDb模块安装及其使用详解
2018/02/23 Python
Python爬虫框架Scrapy常用命令总结
2018/07/26 Python
python输入整条数据分割存入数组的方法
2018/11/13 Python
Python给定一个句子倒序输出单词以及字母的方法
2018/12/20 Python
Python 改变数组类型为uint8的实现
2020/04/09 Python
澳大利亚女士时装在线:Rockmans
2018/09/26 全球购物
三星印度官网:Samsung印度
2019/08/03 全球购物
英国珠宝网站Argento: PANDORA、Olivia Burton和Nomination等
2020/05/08 全球购物
高中生学习生活的自我评价
2013/11/27 职场文书
《小鹰学飞》教学反思
2014/04/23 职场文书
企业标语口号
2014/06/10 职场文书
大学生暑期社会实践证明范本
2014/10/24 职场文书
五一劳动节慰问信
2015/02/14 职场文书
2015年护士长个人工作总结
2015/04/24 职场文书