菜鸟之路-浅谈设计模式之单例设计模式

单例设计模式

定义:确保一个类仅仅有一个实例,并且自行实例化并向整个系统提供这个实例。



单例模式是一种经常使用的软件设计模式。在它的核心结构中仅仅包括一个被称为单例的特殊类。

通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问,从而方便对实例个数的控制并节约系统资源。假设希望在系统中某个类的对象仅仅能存在一个,单例模式是最好的解决方式。



关于单例设计模式的动机

对于系统中的某些类来说。仅仅有一个实例非常重要,比如。一个系统中能够存在多个打印任务,可是仅仅能有一个正在工作的任务;一个系统仅仅能有一个窗体管理器或文件系统;一个系统仅仅能有一个计时工具或ID(序号)生成器。如在Windows中就仅仅能打开一个任务管理器。

假设不使用机制对窗体对象进行唯一化,将弹出多个窗体。假设这些窗体显示的内容全然一致,则是反复对象。浪费内存资源;假设这些窗体显示的内容不一致。则意味着在某一瞬间系统有多个状态,与实际不符。也会给用户带来误解,不知道哪一个才是真实的状态。

因此有时确保系统中某个对象的唯一性即一个类仅仅能有一个实例非常重要。
怎样保证一个类仅仅有一个实例而且这个实例易于被訪问呢?定义一个全局变量能够确保对象随时都能够被訪问。但不能防止我们实例化多个对象。

一个更好的解决的方法是让类自身负责保存它的唯一实例。这个类能够保证没有其它实例被创建。而且它能够提供一个訪问该实例的方法。

这就是单例模式的模式动机


关于单例设计模式的要点

单例模式的要点有三个。一是某个类仅仅能有一个实例。二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
从详细实现角度来说,就是下面三点:一是单例模式的类仅仅提供私有的构造函数,二是类定义中含有一个该类的静态私有对象,三是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。

Java实例:

当一个类的实例能够有且仅仅能够一个的时候就须要用到了。为什么仅仅须要有一个呢?有人说是为了节约内存。但这仅仅是单例模式带来的一个优点。仅仅有一个实例确实降低内存占用。但是我觉得这不是使用单例模式的理由。

我觉得使用单例模式的时机是当实例存在多个会引起程序逻辑错误的时候。比方类似有序的号码生成器这种东西。怎么能够同意一个应用上存在多个呢?



饿汉式单例

public class Singleton {  private static Singleton singleton = new Singleton();  private Singleton(){}  public static Singleton getInstance(){  return singleton;  }  
}

懒汉式单例

public class Singleton {  private static Singleton singleton;  private Singleton(){}  public static synchronized Singleton getInstance(){  if(singleton==null){  singleton = new Singleton();  }  return singleton;  }  
} 
可是这样的单例类型在多线程中是不安全。有可能会出现两个INSTANCE,为什么呢?
假设当唯一实例尚未创建时,有两个线程同一时候调用创建方法,那么它们同一时候没有检測到唯一实例的存在,从而同一时候各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决问题的办法是为指示类是否已经实例化的变量提供一个相互排斥锁(详见双重锁单例。尽管这样会减少效率)。

比較:
饿汉式是线程安全的,在类创建的同一时候就已经创建好一个静态的对象供系统使用,以后不在改变。
懒汉式适合单线程。多线程情况下假设在创建实例对象时不加上synchronized则会导致对对象的訪问不是线程安全的。
从实现方式来讲他们最大的差别就是懒汉式是延时载入, 
他是在须要的时候才创建对象,而饿汉式在载入类时创建实例。 
 饿汉式无需关注多线程问题、写法简单明了、能用则用。可是它是载入类时创建实例、所以假设是一个工厂模式、缓存了非常多实例、那么就得考虑效率问题,由于这个类一载入则把全部实例无论用不用一块创建。 懒汉式的长处是延时载入、缺点是应该用同步。

单例模式的长处:
在内存中仅仅有一个对象。节省内存空间。
避免频繁的创建销毁对象,能够提高性能。
避免对共享资源的多重占用。
能够全局訪问。




适用场景:

因为单例模式的以上长处,所以是编程中用的比較多的一种设计模式。

我总结了一下我所知道的适合使用单例模式的场景:
须要频繁实例化然后销毁的对象。
创建对象时耗时过多或者耗资源过多,但又经经常使用到的对象。


有状态的工具类对象。
频繁訪问数据库或文件的对象。
以及其它我没用过的全部要求仅仅有一个对象的场景。


单例模式注意事项:
仅仅能使用单例类提供的方法得到单例对象,不要使用反射。否则将会实例化一个新对象。


不要做断开单例类对象与类中静态引用的危急操作。
多线程使用单例使用共享资源时,注意线程安全问题。

双重锁形式单例(懒汉式进阶版。哈哈)

 public static class Singleton{private static Singleton instance=null;private Singleton(){//do something}public static Singleton getInstance(){if(instance==null){synchronized(Singleton.class){if(null==instance){instance=new Singleton();}}}return instance;}
}
(有些朋友搞不懂为什么要推断两次Instance==null,由于在多线程中第一次推断时可能有两个或者多个instance==null。那么在synchronized锁里第一个instance已经new出来了,第二个或者后面进入的假设不推断就会反复new对象出来,所以在里面多一层推断确保Instance实例仅仅有一个)
这样还是有一个缺点就是:就是在一个线程还未全然初始化该对象时,而那个变量已经显示为被初始化,那么其它线程可能去使用这个未被全然初始化的实例,造成系统的崩溃。

只是这个在java5以上能够安全执行。


第二种完美实现的实现既线程安全又延迟载入的模式(Initialization on demand holder)使用静态内部类  演示样例:

Public class Singleton{Private Singleton(){};Public static class Singleton1{Private static final Singleton instance = new Singleton();
}    Public static Singleton getInstance(){Return Singleton1.instance;
}
}

这样就能保证在第一次调用getInstance()方法时,才会去初始化instance实例,并且该实例被定义为static,仅仅会被初始化一次。(这样的方法是网上看的,我还未用过,以后能够试试。哈哈大笑)

此文由本人从网上浏览总结而出。如需转载,请注明出处,谢谢!





当一个类的实例能够有且仅仅能够一个的时候就须要用到了。为什么仅仅须要有一个呢?有人说是为了节约内存,但这仅仅是单例模式带来的一个优点。仅仅有一个实例确实降低内存占用,但是我觉得这不是使用单例模式的理由。我觉得使用单例模式的时机是当实例存在多个会引起程序逻辑错误的时候。比方类似有序的号码生成器这种东西,怎么能够同意一个应用上存在多个呢?

转载于:https://www.cnblogs.com/yfceshi/p/7061055.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371886.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MVC如何使用开源分页插件shenniu.pager.js

最近比较忙,前期忙公司手机端接口项目,各种开发调试发布现在几乎上线无问题了;虽然公司项目忙不过在期间抽空做了两件个人觉得有意义的事情,一者使用aspnetcore开发了个人线上项目(要说线上其实只能ip访问,…

四. 基于环视Camera的BEV感知算法-PETR

目录 前言0. 简述1. 算法动机&开创性思路2. 主体结构3. 损失函数4. 性能对比5. PETRv2总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》,链接。记录下个人学习笔记,仅供自己参考 本次课程我们来学习下课程第四章——基…

Java泛型面试问题

Java面试中的通用面试问题在相当长的时间内在Java 5周围越来越普遍,许多应用程序都转移到Java 5上,并且几乎所有新的Java开发都发生在Tiger(Java 5的代号)上。 泛型和Java 5功能(例如Enum)的重要性&#xf…

隐层元素闪一下_太阳一直依靠什么元素在燃烧,地球上的重元素又是怎么来的?...

本文基于回答网友一个这样的问题:太阳目前氢核聚变是氦碳氧稳定燃烧地球上的铁镍重元素哪里来的?可以说,这是一个毫无逻辑乱七八糟的问题,但既然邀请回答,就从中挑出几个稍显合理的问题说明一下。太阳核心每时每刻都在…

基于Token的WEB后台认证机制

基于Token的WEB后台认证机制 几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RESTful API 使用的最简单的认证方式,只需提供用户名密码即可&#xf…

saltstack

第一:安装前准备: 声明我用的是ubuntu 16.04的系统 1.修改主机名,并保证两台机器可以互相ping同主机名 ip1 master_hostname ip2 slave_hostname 第二:安装 服务器安装 yum install salt-master -y客户端安装 yum install salt…

ios 百度地图指定区域_获取百度地图可视区域范围的数据

有个业务场景,需要根据获取到的地图区域显示,根据相应的经纬度反查 左侧区域的会议室。思路:1.得到百度地图可视区域--可视区域的中心点2.可视区域的四个角的其中两个(东北角西南角)http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_refer…

使用WS-Trust / STS采样器扩展JMeter

JMeter没有对WS-Security或WS-Trust的任何内置支持,这使我为JMeter开发了此STS Sampler –可以在负载测试STS时使任何人的生活变得更好。 首先,您需要拥有Apache JMeter发行版。 我正在使用v2.7。 然后,您可以从此处下载sts.sampler.zip –解…

vue怎么改logo_vue全家桶项目构建教程

前言vue是现阶段很流行的前端框架,很多人通过vue官方文档的学习,对vue的使用都有了一定的了解,但再在项目工程化处理的时候,却发现不知道改怎么更好的管理自己的项目,如何去引入一些框架以及vue全家桶其他框架的使用&a…

stm32 内部sram大小_在SRAM、FLASH中调试代码的配置方法(附详细步骤)

聊天界面发送嵌入式大杂烩获取1TB大杂烩资料包STM32的FLASH擦写次数有限(大概为1万次),所以为了延长FLASH的使用时间,我们平时调试时可以选择在SRAM中进行硬件调试。除此之外,SRAM 存储器的写入速度比在内部 FLASH 中要快得多,所以…

自定义控件_VIewPager显示多个Item

一直以来想搞明白这个不完全的VIewPager是怎么做到的&#xff0c;有幸看到这片篇文章 有二种实现方法 1.设置的属性 1.clipChildren属性 2.setPageMargin 3.更新Item外界面 2.重写getPageWidth public class MultiplePagerAdapter extends PagerAdapter { private List<I…

华为怎么改输入法皮肤_微信和QQ个性键盘皮肤

hello大家好&#xff0c;今天是2019年1月1号&#xff0c;祝大家新年快乐今天是新年的第一天&#xff0c;所以说给大家介绍一个好玩的&#xff0c;微信和QQ都能设置的个性的键盘皮肤&#xff0c;看下图&#xff0c;这样的个性的键盘主题怎么设置呢&#xff1f;其实很简单&#x…

用金万维怎么设置路由器_家用路由器怎么设置 家庭路由器设置方法【图文】...

这里以TP-link的无线路由器为例&#xff0c;教一下怎么调试路由器上网。准备工具:网线两条&#xff0c;电脑或者手机&#xff0c;用手机的话就不需要用网线了1、用网线连接光纤猫与路由器&#xff0c;光猫的LAN1口与路由器的WAN相连。路由器的LAN任意一个口用网线连接电脑。2、…

Liferay –简单主题开发

实际上&#xff0c;Liferay的6.1版本已经走了很长一段路&#xff0c;该版本完全支持JSF和IceFaces。 我的目标是使它成为我们团队中的标准协作工具&#xff0c;因此我仍在尝试学习它的精髓。 好的软件应用程序可以解决问题&#xff0c;但是好的软件应用程序不仅可以解决问题&am…

springmvc初步配置

导包/添加依赖&#xff1a;<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springfram…

行号 设置vim_在VSCode里面配置Vim正确姿势(细节解析)

一、导论对于不用vim的人来说&#xff0c;vim简直是个噩梦&#xff0c;复杂的指令、丑陋的界面、令人头痛的配置文件&#xff0c;任何一项都足以劝退一大波人&#xff0c;但是对于已经习惯了使用vim的人来说&#xff0c;vim简直就是马良神笔&#xff0c;似乎vim除了生孩子什么都…

巡回沙龙_美浮特全国巡回沙龙第一期结束撒花!

科技美肤&#xff0c;无龄焕变。美浮特2019全国美肤巡回沙龙第一期活动圆满结束&#xff01;优秀的小伙伴&#xff0c;雅致的茶歇环境&#xff0c;精美的甜点小食&#xff0c;理论与体验并行的肤感测试课堂……不知道是哪一个环节给大家留下了深刻的印象呢&#xff1f;首先让我…

UIAutomation识别UI元素

MS UI Automation&#xff08;Microsoft User Interface Automation&#xff1a;UIA&#xff09;是随.net framework3.0一起发布的&#xff0c;虽然在如今这个几乎每天都有各种新名词、新技术出来的所谓的21世纪&#xff0c;它显得已经有些过时了。前些日子&#xff0c;正好一个…

【C++第一个Demo】---控制台RPG游戏3【登陆菜单树】

【登陆系统--树结构】 1 首先我这里设计&#xff0c;由一个基类MainMenu构建树结构&#xff0c;并实现控制台上菜单之间的切换和返回操作 1 #ifndef _UI_BASE_H_2 #define _UI_BASE_H_3 4 #include <string>5 #include <vector>6 #include"..//Marco.h"7…

不存在_施文忠 | ”存在“与“不存在”——巴蜀文明概论

海德格尔有句名言&#xff1a;“存在者存在&#xff0c;不存在者不存在&#xff01;”四川&#xff0c;一个伟大的存在&#xff0c;偏偏存在于四川的口头禅却是“不存在”。在不存在中追求存在&#xff0c;在存在中摆脱存在。六月白鹿镇&#xff0c;书院学习了《李白与海德格尔…