what's the 单例模式
what's the 单例模式
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例
对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。
实现单例模式4中方式
1.文件导入
文件导入实现单例模式的方式,主要是在一个py文件中创建要单例的类,然后实例化该类,得到该类的对象。以后调用的时候用文件导入的方式导入该对象,直接用对象.方法,无论使用该对象多少次,都只有一个实例对象在运行,即实现单例模式。
参考:django的admin和自己写的stark的site
2.类的方式实现(加锁是为了支持多线程)
# # 单例模式:支持多线程情况 import time
import threading
class Singleton(object):
#创建锁,为多线程
_instance_lock = threading.Lock() def __init__(self):
time.sleep(1)#模拟多线程阻塞 @classmethod
def instance(cls, *args, **kwargs):
# 判断进程,若省略这步直接加锁的话会使得每个进程来时无论实例化与否都加锁才验证,会造成延迟
if not hasattr(Singleton, "_instance"):
with Singleton._instance_lock:#为应对多线程加锁
if not hasattr(Singleton, "_instance"):#判断线程
Singleton._instance = Singleton(*args, **kwargs)#实例化
return Singleton._instance#得到单例对象 def task(arg):
obj = Singleton.instance()
print(obj) #批量创建多线程
for i in range(10):
t = threading.Thread(target=task,args=[i,])
t.start()
time.sleep(20) #单进程
obj = Singleton.instance()
print(obj)
#该方式的弊端:使用时必须先说明以后用单例模式时得用obj = Singleton.instance()
#若公司有个小白进来用obj = Singleton()的话就不是单例了
该方式的弊端:使用时必须先说明以后用单例模式时得用obj = Singleton.instance()若公司有个小白进来用obj = Singleton()的话就不是单例了
3.类中基于基于__new__方式实现 (加锁是为了支持多线程)
import time
import threading
class Singleton(object):
#创建锁,为多线程
_instance_lock = threading.Lock() def __init__(self):
pass def __new__(cls, *args, **kwargs):
#实例化时就判断
if not hasattr(Singleton, "_instance"):
with Singleton._instance_lock:
if not hasattr(Singleton, "_instance"):
Singleton._instance = object.__new__(cls, *args, **kwargs)
return Singleton._instance obj1 = Singleton()
obj2 = Singleton()
print(obj1,obj2) def task(arg):
obj = Singleton()
print(obj) for i in range(10):
t = threading.Thread(target=task,args=[i,])
t.start() # 比方式2的优点:想用实现单例模式直接用obj = Singleton()即可,再也不用担心小白乱来了
与方式2相比的优点:想实现单例模式直接用obj = Singleton()即可,再也不用担心小白乱来了
4.基于metaclass的方式实现(加锁是为了支持多线程)
import threading class SingletonType(type):
_instance_lock = threading.Lock()
def __call__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
with SingletonType._instance_lock:
if not hasattr(cls, "_instance"):
cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
return cls._instance class Foo(metaclass=SingletonType):
def __init__(self,name):
self.name = name obj1 = Foo('name')
obj2 = Foo('name')
print(obj1,obj2) # 分析:Foo类是其元类的对象,在Foo类加括号时(实例化Foo类得到obj)首先执行其元类的__call__方法,
# 会判断该类是否有实例,若有的话不再创建,即完成单例模式
分析:Foo类是其元类的对象,在Foo类加括号时(实例化Foo类得到obj)首先执行其元类的__call__方法,会判断该类是否有实例,若有的话不再创建,即完成单例模式
总结
四种单例模式都有其一定的应用场景,都能支持多线程的情况,文件导入的形式无需加锁。一般情况下用文件导入和__new__方式实现的情况较多,在源码中基于metaclass的方式实现较少。
what's the 单例模式的更多相关文章
- C++实现线程安全的单例模式
在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...
- 23种设计模式--单例模式-Singleton
一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- java设计模式之--单例模式
前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...
- 设计模式C#合集--单例模式
单例模式 代码: 第一种: private static Singleton singleton = null; private Singleton() { } public static Singl ...
- 设计模式之单例模式(Singleton)
设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
- GOF23设计模式之单例模式
·核心作用: -保证一个类只有一个实例,并且提供一个访问该实例的全局访问点. ·常见应用场景: -Windows的Task Manager(任务管理器)就是很典型的单例模式 -Windows的Recy ...
- GJM : C#设计模式(1)——单例模式
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- PHP设计模式(四)单例模式(Singleton For PHP)
今天讲单例设计模式,这种设计模式和工厂模式一样,用的非常非常多,同时单例模式比较容易的一种设计模式. 一.什么是单例设计模式 单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
随机推荐
- [Tensorflow] Object Detection API - prepare your training data
From: TensorFlow Object Detection API This chapter help you to train your own model to identify obje ...
- vue分页组件
<template> <div> <ul class="pagination"> <li @click="goTo(1)&quo ...
- mysql基础---->mybatis的批量插入(一)
这里面记录一下使用mybatis处理mysql的批量插入的问题,测试有可能不准.只愿世间风景千般万般熙攘过后,字里行间,人我两忘,相对无言. mybatis的批量插入 我们的测试主体类是springb ...
- sencha touch 百度地图扩展(2014-12-17)
上个版本http://www.cnblogs.com/mlzs/p/3666466.html,新增了一些功能,修复了一些bug 扩展代码如下: Ext.define('ux.BMap', { alte ...
- linux Email 体系
大致了解了DNS与邮件服务器之间的关系后,接下来我们介绍邮件到底是如何传送到目的邮件主机的.下面我们分成“寄信”与“收信”两个主要的邮件服务器使用方式进行介绍.先说明关于“寄信”的部分.通常我们都是使 ...
- Android摸索-二、解决Android SDK Manager下载太慢问题
下载Android SDK Manger 那个速度………… 有了这个再也不用担心了 1.打开android sdk manager 2.打开tool->options 按图片中输入参数:mi ...
- ng之自定义指令
最近开始研究并使用angular,今天就来简单讲讲对于ng中自定义指令的一下使用心得吧! 相信用过ng的人都对ng中的指令有所了解,指令,我将其理解为AngularJS操作HTML element的一 ...
- db2 MON_GET_PKG_CACHE_STMT 表函数 抓取分析SQL
MON_GET_PKG_CACHE_STMT 表函数 还可以使用 MON_GET_PKG_CACHE_STMT 表函数来查询当前 PACKAGE CACHE 中 SQL 语句(包括动态 SQL 和静态 ...
- 品尝阿里云容器服务:初步尝试ASP.NET Core Web API站点的Docker自动化部署
部署场景是这样的,我们基于 ASP.NET Core 2.0 Preview 1 开发了一个用于管理缓存的 Web API ,想通过阿里云容器服务基于 Docker 部署为内网服务. 在这篇博文中分享 ...
- [No0000157].net core项目中拼音,excel,pdf处理库
汉字转拼音 1. HxfPinYin public static class Pinyin { public static string ConvertEncoding(string text, En ...