设计模式:单例模式
Posted chenjiabing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式:单例模式相关的知识,希望对你有一定的参考价值。
什么是单例模式
- 单例模式(Singleton Pattern)是一个比较简单的模式,实际应用很广泛,比如 Spring 中的
Bean
实例就是一个单例对象。 - 文章首发于作者微信公众号【码猿技术专栏】设计模式:单例模式,原创不易,喜欢的支持一下!!!!
- 定义:确保某一个类 只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式的优缺点
- 评价任何一种事务都要从两个方面去看,不能单一的评价。下面来看看单例模式有什么优缺点。
优点
- 只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。
- 单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在 内存中,避免对同一个资源文件的同时写操作。
- 单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如可以设计一个单 例类,负责所有数据表的映射处理。
缺点
- 单例模式一般没有接口,很难扩展(根据环境而定)。
- 单例模式与单一职责原则有冲突。一个类应该只实现一个逻辑,而不关心是否是单例的。
单例模式的实现
- 单例模式有很多的实现方式,但是各种实现的方式都有其优缺点,下面来看看各种的实现方式。
- 单例模式的实现满足以下几点:
- 构造方法私有。
- 有一个静态方法获取该类的实例。
- 该类保证只有一个实例。
懒汉式
- 懒汉式是当用到这个对象的时候才会创建。
- 优点:只有用到的时候才会创建这个对象,因此节省资源。
- 简单的实现如下:
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 上面的代码算是基本满足了单例模式,但是不能满足线程安全,一旦在多线程的环境下仍然是不能保证该类是单例的。
- 如何保证线程安全,当然是加锁了,我们可以加线程同步锁
synchronized
,实现如下:
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 此种实现方式虽然满足了线程安全,但是加锁势必会影响性能。
饿汉式
- 饿汉式和懒汉式恰巧相反,在类加载的时候就创建实例。
- 优点:还没用到就创建,浪费资源。
- 缺点:在类加载的时候就创建,线程安全。
- 实现如下:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
双重校验锁
- 属于懒加载的一种实现方式,采用双重校验的机制,在多线程的情况仍然保持高性能。
- 实现如下:
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
匿名内部类/静态内部类
- 利用静态变量、静态代码块、静态方法都是在类加载的时候只加载一次的原理。
- 实现如下:
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
总结
- 单例模式的实现虽然很简单,但是也要确保实现的性能和线程安全的问题。
- 单例模式的实现主流的就是以上介绍的几种,分别是
懒汉式线程不安全
、懒汉式线程安全
、饿汉式
、双重校验锁的实现
、静态内部类的实现
。这几种方式各有优缺点,陈某推荐使用静态内部类的实现方式。 - 单例模式也是Spring使用的一种设计模式,保证了
Bean
的单实例才能管理和监控Bean的创建和销毁。
以上是关于设计模式:单例模式的主要内容,如果未能解决你的问题,请参考以下文章