被说了很多遍的设计模式---单例模式
[把你的理性思维慢慢变成条件反射]
本文,我们讲介绍单例模式,文章主题结构与上文一致。惯例,先来看看我们示例工程的环境:
经典问题:
思路分析:
要点二:无论是自己创建,还是被其他对象创建或引用,均不能破坏唯一性。
【由于单例模式是较为常用的一种设计模式。所以我们调整一下顺序,先说明概念,然后在展示示例代码】
模式总结:
单例模式结构图:
单例模式:
组成部分:
模板代码:
懒汉式单例:
特点:
- 延迟加载,只有到真正使用是才生成一个单例对象供调用对象使用。并且,以后不会再生成新的该对象。
- 拥有一个private修饰的静态变量
- 拥有一个private修饰的构造方法,方式被外部的对象调用。
- 拥有一个public修饰的静态工厂方法,返回一个具体的实例。
package com.csdn.ingo.gof_Singleton;public class Singleton {private static Singleton instance;private Singleton(){}public static Singleton getInstance(){if(instance==null){instance = new Singleton();}return instance;}
}
package com.csdn.ingo.gof_Singleton;public class WIndow {public static void main(String[] args) {Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();if(s1==s2){System.out.println("s1==s2");}}
}
懒汉式单例的问题:
当发生多线程同时使用该对象时,会发生线程不安全的问题。很有可能生成多个对象。
解法:
增加线程锁,双重锁检查,静态内部类(推荐)等方法。
①增加同步锁:
public static synchronized Singleton getInstance() { if (single == null) { single = new Singleton(); } return single;
}
②双重锁检查:
public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; }
③静态内部类:(内部类在调用时才进行加载)
public class Singleton { private static class LazyHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return LazyHolder.INSTANCE; }
}
饿汉式单例:
特点:
- 在类进行加载时就创建了一个单例对象,并且之后一直使用该对象。
- 拥有一个private final static 修饰的,并且自身带初始化的变量。
package com.csdn.ingo.gof_Singleton.two;public class Singleton {private Singleton() {}private final static Singleton instance = new Singleton();public static Singleton getInstance() {return instance;}
}
以上两种单例模式区别:
线程安全性:
饿汉式的单例模式:一定是线程安全的。懒汉式的单例模式:其自身是非线程安全的,但是能够通过其他①②③三种方式实现安全性。
性能:
饿汉式的单例模式:
在启动实例化过程时,就会创建一个单例对象。因此,在时间上而言,实例化启动的时间较长,使用时的调用时间相对较短。另外,该单例对 象会一直存在于内存当中。
懒汉式的单例模式:
在启动实例化过程中,没有创建一个单例对象,而是在使用时才创建一个单例对象。因此,在时间上而言,实例化启动的时间较短,使用时的 调用时间相对教程。另外,在实例化之后,该单例对象也会一直存在于内存当中。
除此之外:
上文第①种方式:每次都需要使用同步锁,对性能会产生不利影响。
上文第②种方式:在第一次调用时,使用同步锁。后续不再使用同步锁。对性能影响较为有限。
上文第③种方式:内部类在初始化时未生成一个单例对象,而是等到第一次调用时才生成。在调用时,由于Classloader的特殊性,保证实例化的对象有且只有一个单例对象。因此,其表现效果类似于②。
枚举式单例:
特点:
- 通过枚举定义的方式声明与使用单例对象
- 线程安全:枚举的创建过程本身是线程安全的
- 不会因为序列化而产生新实例:在传统的单例模式中,一旦实现了Serializable接口,其就不再是单例的对象了,因为readObject()方法内次总是返回一个新的示例对象,此过程类似于Java中的构造器。而对于枚举实现单例,其实从JVM中防止了此问题。
package com.csdn.ingo.gof_Singleton.thire;public enum Singleton {Instance; // 定义一个枚举的元素,就代表Singleton的一个实例private Singleton() {}
}
双重锁Volatile检查的单例模式:
特点:
- volatile关键字:保证该对象始终是最新的值(在Java1.5版本之后上文的双重锁存在漏洞,具体原因,请各位看官查看volatile解释即可)
- 其他类似于上文双重锁检查。
package com.csdn.ingo.gof_Singleton.five;public class Singleton {private volatile static Singleton singleton;private Singleton() {}public static Singleton getInstance() {if (singleton == null) {synchronized (Singleton.class) {if (singleton == null) {singleton = new Singleton();}}}return singleton;}
}
反思:
应用场景:
- 在系统内只需要有且只有一个该对象时,如日志对象,ID生成器对象,等等。
- 客户端对单例对象只允许使用一个公共访问点。
优点:
- 单例模式提供了对实例对象的唯一入口。严格控制了客户的方式与路径。
- 节约系统资源,节约该对象的响应时间。
- 单例模式可以扩展为指定数量的对象生成器。其效果类似于连接池的创建过程,取得资源与效率的平衡。
缺点:
- 单例模式不符合“开闭原则”。对单例的维护只能修改单例类本身。
- 单例模式不符合“单一职责原则”。单例类本身负责创建对象,有包含了对象的其他方法。
- Java垃圾回收机制会将长时间未使用的,实例化的共享的单例对象进行回收,导致该对象的状态丢失。
-------------------------------------------------------------------------------------------------------------------------------------
至此,被说了很多遍的设计模式---单例模式 结束
参考资料:
图书:《大话设计模式》
其他博文:
http://blog.csdn.NET/lovelion/article/details/7563445
http://cantellow.iteye.com/blog/838473
https://my.oschina.net/zhoujy/blog/134958
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
http://www.cnblogs.com/zhengbin/p/5654805.html
http://javarevisited.blogspot.jp/2012/07/why-enum-singleton-are-better-in-java.html
被说了很多遍的设计模式---单例模式相关推荐
- 设计模式-单例模式-注册式单例模式-枚举式单例模式和容器式单例模式在Java中的使用示例
场景 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例: 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例_霸道流氓气质的博客- ...
- 设计模式----创建型设计模式(单例模式、工厂方法模式、构建者模式)
创建型设计模式 单例模式(Singleton Pattern) 单例模式介绍 代码演示 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 懒汉式(线程安全, ...
- 软件设计模式“单例模式”和“工厂模式”
软件设计模式"单例模式"和"工厂模式" 单例模式 什么是单例模式 单例模式的实现方式有哪些 单例模式的优缺点 单例模式的应用场景 总结 工厂模式 什么是工厂模式 ...
- 设计模式——单例模式、工厂模式
设计模式--单例模式.工厂模式 一.六大设计原则 开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭.在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热 ...
- Python设计模式-单例模式
Python设计模式-单例模式 基于Python3.5.2,代码如下 #coding:utf-8 import threading import timeclass Singleton(object) ...
- Android设计模式——单例模式(Singleton)
二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元 ...
- 【学习笔记】ABAP OOD设计模式 - 单例模式
ABAP OOD设计模式 - 单例模式 整理转自-<SAP ABAP 面向对象程序设计(原则.模式及实践)> 单例模式(Singleton Pattern)是常用的且较为简单的软件设计模式 ...
- Go 语言实现 23 种设计模式 单例模式
Go 语言实现 23 种设计模式 单例模式 单例模式 单例模式是一种常用的软件设计模式,在使用过程中,单例对象的类只有一个实例.使用单例模式,1 可以节省内存等资源,例如windows操作系统的资源管 ...
- java singleton inner class_Java面向对象设计模式-单例模式
Java面向对象设计模式-单例模式 2020-05-28 589 0 单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点,有多重实现方式. 一.饿汉式单例模式,构造方法私有化,在加载类Sin ...
最新文章
- 典型用户描述及进一步需求分析
- android dialog加载中动画效果
- centos7搭建Linux集群,CentOS 7下Kafka集群安装
- Python面试题(第二篇)
- 【Infragistics教程】在javascript构造函数中创建基本继承
- android手机连接PC后怎样切换为U 盘模式
- Python - SimpleHTTPServer and CGIHTTPServer
- Asp.net 2.0 自定义控件开发[实现自动计算功能(AutoComputeControl)][示例代码下载][续]...
- C++11nullptr
- DB2 亲身实例(GUI界面) 加 笔记和注意事项
- vue 组件创建与销毁
- iocomp入门教程(绘制Plot)
- 时间管理工具推荐,助你实现高效能,慢生活
- 游戏测试的概念是什么?测试方法和流程有哪些?
- 发送速率(传输速率)和传播速率
- Win10下WinRAR“拒绝访问”解决+获取everyone权限
- linux安全审计和加固工具-lynis
- cloudreve 开源私有网盘(带离线下载)
- gb 28181的20位编码简介
- java jtextarea 超出_java – 如何保持JTextArea的大小不变?