23种设计模式之单例模式
来源:互联网 发布:华盛顿和李大学知乎 编辑:程序博客网 时间:2024/06/10 17:29
定义:确保一个类中只有一个实例,而且自行实例化并向整个系统提供这个实例。或者说某种类型的对象有且只有一个。
实现单例模式主要有以下几个关键点:
- 构造函数不对外开放,一般为Private
- 通过一个静态方法或者枚举返回单例类对象
- 确保单例类的对象有且只有一个,尤其是在多线程环境下
- 确保单例类对象在反序列化时不会被重新构建对象。
单例的实现方式有多重:饿汉式,懒汉式,静态内部类,双重校验锁(DCL),枚举等,推荐使用静态内部类和双重校验锁。
1.饿汉式:
/** * Created by jmfstart on 2017/5/5. * 饿汉式 */public class Singleton { private static final Singleton singleton = new Singleton(); private Singleton() { } public static Singleton getInstance() { return singleton; }}
这种方式基于类加载机制避免了多线程的同步问题,不过,instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到懒加载的效果。
2.懒汉式(线程不安全的)
/** * Created by jmfstart on 2017/5/5. * 懒汉式 */public class Singleton { private static Singleton singleton ; private Singleton() { } public static Singleton getInstance() { if(singleton == null) { singleton = new Singleton(); } return singleton; }}
这种写法懒加载很明显,但是致命的是在多线程不安全。
3.懒汉式(线程安全的)
public class Singleton { private static Singleton instance; private Singleton (){ } public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
大家细想,假如对象已经被初始化instance,现在每次调用getInstance()方法时都会进行同步,这会消耗不必要的资源。不建议使用
4.Double Check Lock(DCL)实现单例
/** * Created by jmfstart on 2017/5/5. * DCL方式实现 */public class Singleton { private static Singleton singleton ; private Singleton() { } public static Singleton getInstance() { if(singleton == null) { synchronized (Singleton.class){ if(singleton == null) { singleton = new Singleton(); } } } return singleton; }}
优点:资源利用率高。
缺点:第一次加载时反应稍慢。在高并发环境下也有一定的缺陷,虽然发生的概率很小。
DCL模式是使用最多的单例实现方式,它能够在需要时才实例化单例对象。这种方式一般能够满足需求。
5.静态内部类单例模式
DCL在某些情况下出现失效的问题,这个问题被称为双重检验锁(DCL)失效,建议使用静态内部类替代
/** * Created by jmfstart on 2017/5/5. * 静态内部类实现单例 */public class Singleton { private Singleton() { } public static Singleton getInstance() { return SingletonHolder.singleton; } //静态内部类 private static class SingletonHolder { private static Singleton singleton = new Singleton(); }}
这种方式不仅能够保证线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化,所以这是推荐使用的单例模式的实现方式。
6.枚举类实现单例
/** * Created by jmfstart on 2017/5/5. * 枚举实现单例 */public enum Singleton { INSTANCE; public void doSomething() { System.out.println("do sth."); }}
这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum特性,用这种方式写不免让人感觉生疏,在实际工作中,我也很少看见有人这么写过。
7.使用容器实现单例模式
这种实现方式比较另类
/** * Created by jmfstart on 2017/5/5. * 单例的集合,便于管理 */public class SingletonManager { private static Map<String,Object> objectMap = new HashMap<>(); private SingletonManager(){ } private static void registerService(String key,Object instance){ if(objectMap.containsKey(key)) { objectMap.put(key,instance); } } public static Object getService(String key){ return objectMap.get(key); }}
单例模式总结
优点
a.单例模式在内存中只有一个实例,减少内存开支,非常适合频繁的创建和销毁一个对象的场景
b.由于单例模式只生成一个实例,所以减少了系统的性能开支,使用永久驻留内存的方式来解决。
c.单例模式避免了对公共资源的多重占用。如读写文件操作等等。
d.单例模式可以在系统设置全局的访问点。
缺点
a.单例模式一般没有接口,扩展很困难,除了修改代码基本没有其他方法可以实现。
b.单例对象如果持有Context,那么很容易引起内存泄露,最好传递Application Context.
- 23种设计模式 之单例设计模式
- 23种设计模式之 单例
- 23种设计模式学习之东拼西凑-------单例模式
- 23种设计模式之单例模式(Singleton)
- 23种设计模式之单例模式
- c++23种设计模式之单例模式
- 23种设计模式简单概述之单例模式
- 23种设计模式之python实现--单例模式
- java 23种设计模式之单例模式
- 23种设计模式之单例模式
- 23种设计模式之单例模式
- 23种设计模式之【单例模式】
- 黑马程序员-23种设计模式之单例模式
- 23种设计模式C++实例之单例模式
- 23种设计模式之单例模式
- 23种设计模式之单例模式
- 23种设计模式之单例模式
- 23种设计模式之——单例模式
- 细说 javaScript 创建对象
- Pytorch遇到的几个问题
- solr学习笔记(3)--使用solrj调用solr服务
- Azure Active Dirctory集成本地Active Dirctory
- Batch Normalization 学习笔记
- 23种设计模式之单例模式
- Matplotlib库
- qsort细节用法
- mybatis中动态sql常用的标签
- chrome、webkit内核的各种浏览器、新版IE(微软Edge)浏览器惊天大bug集合
- Ubuntu下搭建samba服务
- OpenStack创建2台VM之间的DHCP服务设置
- Codeforces Round #411 (Div. 2) B. 3-palindrome
- 【软考】设计模式-命令模式