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 单例模式的更多相关文章

  1. C++实现线程安全的单例模式

    在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...

  2. 23种设计模式--单例模式-Singleton

    一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...

  3. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  4. java设计模式之--单例模式

    前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...

  5. 设计模式C#合集--单例模式

    单例模式 代码: 第一种: private static Singleton singleton = null; private Singleton() { } public static Singl ...

  6. 设计模式之单例模式(Singleton)

    设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...

  7. GOF23设计模式之单例模式

    ·核心作用: -保证一个类只有一个实例,并且提供一个访问该实例的全局访问点. ·常见应用场景: -Windows的Task Manager(任务管理器)就是很典型的单例模式 -Windows的Recy ...

  8. GJM : C#设计模式(1)——单例模式

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  9. PHP设计模式(四)单例模式(Singleton For PHP)

    今天讲单例设计模式,这种设计模式和工厂模式一样,用的非常非常多,同时单例模式比较容易的一种设计模式. 一.什么是单例设计模式 单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对 ...

  10. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

随机推荐

  1. SSM框架整合搭建教程

    自己配置了一个SSM框架,打算做个小网站,这里把SSM的配置流程详细的写了出来,方便很少接触这个框架的朋友使用,文中各个资源均免费提供! 一. 创建web项目(eclipse) File-->n ...

  2. docker_File 执行报错总结

    编写dockerfile [root@linux-node1 ~/dk]# cat Dockerfile # this is a docker File FROM centos MAINTAINER ...

  3. Android异步处理系列文章四篇之四 AsyncTask的实现原理

    Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...

  4. hashcode、equals和 ==详解

    两个对象值相同(x.equals(y) == true),则一定有相同的hash code: 这是java语言的定义: 因为:Hash,一般翻译做“散列”,也有直接音译为"哈希"的 ...

  5. iOS Xcode, 解决“Could not insert new outlet connection”的问题。

    在Xcode中,我们能够在StoryBoard编辑界面或者是xib编辑界面中通过"Control键+拖拽"的方式将某个界面元素和相应的代码文件连接起来,在代码文件里创建outlet ...

  6. [原]openstack-kilo--issue(十)ERROR: openstack Unable to establish connection to http://controller:35357/v3/auth/tokens

    ====环境== openstack :kilo CentOS : 7 ====问题=== 在没有关vm的情况下,重启了controller. 问题一: 在使用nova service-list 或者 ...

  7. 理解PEP333-WSGI

    声明:这篇文章只是为了整体理解WSGI,会忽略很多细节,要详细了解请参看文后的参考资料 WSGI概述 WSGI全称是Python Web Server Gateway Interface(Python ...

  8. Win10配置分屏显示

    新买的电脑是17.3的,单独打开一个界面总是感觉地方有点浪费,研究了下分屏使用. 以下是现在分屏后的电脑界面. 设置说明 目的:将三个窗口分屏布满屏幕,便于多任务操作. 步骤: 1.按住鼠标左键,将w ...

  9. H - Windows Message Queue

    Message queue is the basic fundamental of windows system. For each process, the system maintains a m ...

  10. MySQL多实例部署与优化

    MySQL安装 ##上传MySQL安装包## mkdir /home/oldboy/tools -p cd /home/oldboy/tools/ ###wget -q http://mirrors. ...