单例模式

单例模式,是常见的设计模式之一,一般来说,是开发人员较早接触的模式之一。嘻嘻,包括我~~~

分类

一般来说,分两种:

  • 饿汉模式。非常饿嘛,一开始就加载了,如果这个资源在以后的运行中没有用到,又加载了这个资源,就显得浪费了,所以资源利用率不高。
  • 懒汉模式。非常懒嘛,能不加载就不加载了,到实际用到的时候才加载,所以,是延迟加载的单例模式。

注意的小地方

写一个单例虽然简单,有几点需要注意:

  1. 取得单例的方法(这里为getInstance)是公开、静态的,不然难道要实例化类后,再从此方法获取单例?
  2. 单例对象也是静态的,可供getInstance方法访问,同时也维持唯一性嘛;也是私有的,避免外部类访问嘛,保证这个实例仅能通过“取得单例的方法”获取
  3. 构造方法是私有的,防止其他类任意实例化

饿汉单例模式(非延迟加载)

来点解渴滴。。。

饿汉单例模式(非延迟加载)

package com.nicchagil.sample.designpattern.No01单例模式.No01非延迟加载模式;

public class Singleton {

    /*
* 1.取得单例的方法(这里为getInstance)是公开、静态的,不然难道要调用类实例化后再从此方法获取单例?
* 2.单例对象也是静态的,可供getInstance方法访问
* 3.构造方法是私有的,防止其他类任意实例化
*/
static Singleton s = new Singleton(); private Singleton() { } public static Singleton getInstance() {
return s;
} }

懒汉单例模式(延迟加载)

普通的懒汉单例模式(即延迟加载),用synchronized控制方法同步,避免线程并发生成多个对象。

比如:

  • A线程判断为对象为空,进入方法体准备实例化对象,但又还没实例化对象,那一个Moment
  • B线程也进行判断对象是否为空,结果当然为空,从而也进入方法体,准备实例化对象,这样就生成了两个不同的对象了,悲催了,哈哈哈哈哈
package com.nicchagil.sample.designpattern.No01单例模式.No02延迟加载模式;

public class Singleton {

    static Singleton s = null;

    private Singleton() {

    }

    public synchronized static Singleton getInstance() {
if (s == null) {
s = new Singleton();
} return s;
} }

另外,如果想效果好一些,可以使用synchronized同步块,从而避免整个方法都同步(毕竟在具体实现中,有些代码不需要同步嘛)

懒汉单例模式的双重判断方式

看了程杰老师的《大话设计模式》,里面巧妙使用了双重判断,再使用synchronized同步块,效率更高,高在哪?(注意:因Java编译优化等原因,用Java实现双重判断方式有可能不生效,所以用Java的话建议不用此方式)

如果没用双重判断,即把外层的判空剥去,每次取实例时都进入同步块,用美女的话来说,多费劲啊!!

双重判断,避免了每次获取实例进入同步块的问题,也解决了并发获取对象的问题:

  • A线程判空后,进入方法体,但还没实例化对象,这时到了B线程
  • B线程判空后,发现也为空,当然也进入方法体
  • 这时,A、B俩都得排队进入同步块了
  • 加入B进入并执行同步块的代码,实例化了单例的对象
  • 轮到A进入同步快,在进行第二次判断,这时,哈哈哈哈哈

用JAVA实现分享下:

package com.nicchagil.sample.designpattern.No01单例模式.No04延迟加载模式_双重判断;

public class Singleton {

    static Singleton s = null;
static Object o = new Object(); private Singleton() { } public static Singleton getInstance() {
/*
* 在获取实例方法中使用设置同步,是为了避免在一线程判断为空后准备实例化单例对象但又还未实例化时,另一线程进行判空后发现单例对象为空进而实例化对象,从而使单例对象并非所指同一对象
* 之所以用双重判断,然后在第一层判断后在嵌套同步块,
* 因为如果每次欲获取单例,都使用同步机制,不仅效率较低,且系统消耗也较大
* 所以,如单例对象已实例化,则无欲进入同步块以实例化单例对象
*/ if (s == null) {
synchronized (o) {
if (s == null) {
s = new Singleton();
}
}
} return s;
} }

【设计模式】常用de单例模式的更多相关文章

  1. linkin大话设计模式--常用模式总结

    linkin大话设计模式--常用模式总结 一,常用设计模式定义 Abstract Factory(抽象工厂模式):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. Adapter( ...

  2. 【白话设计模式四】单例模式(Singleton)

    转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...

  3. php设计模式笔记:单例模式

    php设计模式笔记:单例模式 意图: 保证一个类仅有一个实例,并且提供一个全局访问点 单例模式有三个特点: 1.一个类只有一个实例2.它必须自行创建这个实例3.必须自行向整个系统提供这个实例 主要实现 ...

  4. Java设计模式之《单例模式》及应用场景

    摘要: 原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6510196.html 所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该 ...

  5. Java设计模式之【单例模式】

    Java设计模式之[单例模式] 何为单例 在应用的生存周期中,一个类的实例有且仅有一个 当在一些业务中需要规定某个类的实例有且仅有一个时,就可以用单例模式 比如spring容器默认初始化的实例就是单例 ...

  6. Java设计模式中的单例模式

    有时候在实际项目的开发中,我们会碰到这样一种情况,该类只允许存在一个实例化的对象,不允许存在一个以上的实例化对象,我们将这种情况称为Java设计模式中的单例模式.设计单例模式主要采用了Java的pri ...

  7. C#设计模式学习笔记-单例模式随笔

    最近学习 设计模式,从单例模式入手 啥是单例模式: 要实现一个单例类的话,首先,肯定是不能让用户自行生产的,那就是说明不能让用户new,所以,就必须把构造函数设置成为私有的 因为静态变量的生命周期跟整 ...

  8. IOS设计模式浅析之单例模式(Singleton)

    说在前面 进入正式的设计模式交流之前,扯点闲话.我们在项目开发的过程中,经常会不经意的使用一些常见的设计模式,如单例模式.工厂方法模式.观察者模式等,以前做.NET开发的时候,认真拜读了一下程杰老师的 ...

  9. C#设计模式学习笔记-单例模式(转)

    C#设计模式学习笔记-单例模式 http://www.cnblogs.com/xun126/archive/2011/03/09/1970807.html 最近在学设计模式,学到创建型模式的时候,碰到 ...

随机推荐

  1. struts2--convention-plugin--零配置

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ...

  2. SpringMVC表单标签简介

    在使用SpringMVC的时候我们可以使用Spring封装的一系列表单标签,这些标签都可以访问到ModelMap中的内容.下面将对这些标签一一介绍. 在正式介绍SpringMVC的表单标签之前,我们需 ...

  3. Network | UDP checksum

    1. 校验和 ICMP,IP,UDP,TCP报头部分都有checksum(检验和)字段.IP 首部里的校验和只校验首部:ICMP.IGMP.TCP和UDP首部中的校验和校验首部和数据. UDP和TCP ...

  4. go gomail

    package main //cmd: go get gopkg.in/gomail.v1 import ( "gopkg.in/gomail.v1" ) func main() ...

  5. 阅读廖雪峰老师git教程笔记

    1.首先git是目前世界上最先进的分布式版本控制系统之一.所谓版本控制是针对工作中一些普遍的现象的. 比如,你写一份文档,期间,不断的改善,每次修改都会进行备份,久而久之,会有很多版本的同一份文档,但 ...

  6. LNMP-Linux下Nginx+MySQL+PHP+phpMyAdmin+eAcelerator一键安装包

    LNMP一键安装包是一个用Linux Shell编写的可以为CentOS/RadHat.Debian/Ubuntu VPS(VDS)或独立主机安装LNMP(Nginx.MySQL.PHP.phpMyA ...

  7. LeetCode Minimum Height Trees

    原题链接在这里:https://leetcode.com/problems/minimum-height-trees/ 题目: For a undirected graph with tree cha ...

  8. 如何把自己打造成技术圈的papi酱

    最近半年,一个叫papi酱的平胸女子连续在微博.朋友圈.创业圈刷屏,当之无愧成了中文互联网的第一大网红.呃,你以为我会巴拉巴拉说一堆网工创业的事?NO,今天想借papi酱的话题跟大家一起聊聊程序员如何 ...

  9. H5 新标签用法及解释

    HTML 5 是一个新的网络标准,目标在于取代现有的 HTML 4.01, XHTML 1.0 and DOM Level 2 HTML 标准.它希望能够减少浏览器对于需要插件的丰富性网络应用服务(p ...

  10. CentOS-6 yum安装nginx php53 mysql55 搭建LNMP环境

    1.导入外部软件库 01.rpm -Uvh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/epel-release-6-5.noa ...