详解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的web.py框架并从hello world开始编程
Apr 25 Python
在Python的Tornado框架中实现简单的在线代理的教程
May 02 Python
Python中类型检查的详细介绍
Feb 13 Python
pandas.loc 选取指定列进行操作的实例
May 18 Python
python发送邮件脚本
May 22 Python
python整合ffmpeg实现视频文件的批量转换
May 31 Python
Django admin.py 在修改/添加表单界面显示额外字段的方法
Aug 22 Python
python中必要的名词解释
Nov 20 Python
keras 解决加载lstm+crf模型出错的问题
Jun 10 Python
keras导入weights方式
Jun 12 Python
Appium+Python实现简单的自动化登录测试的实现
Jan 26 Python
解决pycharm下载库时出现Failed to install package的问题
Sep 04 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返回json数据函数实例
2014/10/09 PHP
php查看当前Session的ID实例
2015/03/16 PHP
php获取远程文件的内容和大小
2015/11/03 PHP
Yii2 RESTful中api的使用及开发实例详解
2016/07/06 PHP
微信公众号开发之获取位置信息php代码
2018/06/13 PHP
PJ Blog修改-禁止复制的代码和方法
2006/10/25 Javascript
javascript call方法使用说明
2010/01/11 Javascript
一款基jquery超炫的动画导航菜单可响应单击事件
2014/11/02 Javascript
浅谈javascript实现八大排序
2015/04/27 Javascript
JS控件bootstrap datepicker使用方法详解
2017/03/25 Javascript
详解VUE中常用的几种import(模块、文件)引入方式
2018/07/03 Javascript
对angularJs中$sce服务安全显示html文本的实例
2018/09/30 Javascript
Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)
2019/11/18 NodeJs
Postman内建变量常用方法实例解析
2020/07/28 Javascript
Python抓取淘宝下拉框关键词的方法
2015/07/08 Python
30秒轻松实现TensorFlow物体检测
2018/03/14 Python
python 拷贝特定后缀名文件,并保留原始目录结构的实例
2018/04/27 Python
python 字典修改键(key)的几种方法
2018/08/10 Python
python学生管理系统开发
2019/01/30 Python
Python3之不使用第三方变量,实现交换两个变量的值
2019/06/26 Python
Canvas 文本转粒子效果的实现代码
2019/02/14 HTML / CSS
HTML5 video标签(播放器)学习笔记(一):使用入门
2015/04/24 HTML / CSS
马来西亚网上购物平台:ezbuy
2018/02/13 全球购物
The Kooples美国官方网站:为情侣提供的法国当代时尚品牌
2019/01/03 全球购物
应届生自我鉴定
2013/12/11 职场文书
大二学生学习个人自我评价
2014/01/19 职场文书
疾病防治方案
2014/05/31 职场文书
关于安全的标语
2014/06/10 职场文书
学校总务处领导干部个人对照检查材料思想汇报
2014/10/06 职场文书
2014年平安建设工作总结
2014/11/19 职场文书
2015大学自主招生自荐信范文
2015/03/04 职场文书
银行客户经理培训心得体会
2016/01/09 职场文书
nginx网站服务如何配置防盗链(推荐)
2021/03/31 Servers
我对PyTorch dataloader里的shuffle=True的理解
2021/05/20 Python
Python天气语音播报小助手
2021/09/25 Python
vue实现简易音乐播放器
2022/08/14 Vue.js