单例模式已经是一个老生常谈的话题了,那么该如何正确实现一个单例模式呢?
1. 单例模式是什么
单例模式,顾名思义就是只且只有一个实例,它是创建对象实例的一种手段,对外提供一个全局访问点。在整个应用程序运行期间,针对某个类而言,有且只有一个该类的实例。仅此一家,别无分号!
2. 单例模式的作用及特点
那么有人就问了,为什么只能有一个实例,搞多几个不行吗?首先明确一点,在很多时候,针对某些类而言,应用程序其实并不需要该类的过多实例,一个足矣:比如某些系统工具类,又比如全局计时器、序号发生器这样的类,多个实例不仅浪费内存资源,更容易产生系统错误(想想看如果系统同时存在多个计时器,那以哪一个为准呢)。
通常而言,单例模式的类都具有以下特点:
- 构造器私有,防止外部具备初始化能力
- 自身维护一个单一实例,并对外提供一个静态的公共访问方法
3. 实现单例的五种方式
3.1 饿汉式
1 2 3 4 5 6 7 8 9 10 11
| public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() { return instance; } }
|
3.2 懒汉式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() { if (null == instance) instance = new Singleton();
return instance; } }
|
饿汉式和懒汉式的区别在于instance实例是否延迟初始化,饿汉式是线程安全的,而懒汉式则不是。如果需要在多线程环境下使用,需要将getInstance() 方法申明为 synchronized.
3.3 静态内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Singleton {
private static Singleton instance;
private Singleton() {}
private static class SingletonHolder { private static final Singleton instance = new Singleton(); }
public static Singleton getInstance() { return SingletonHolder.instance; } }
|
3.4 双重检查锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Singleton {
private static Singleton instance;
private Singleton() {} public static Singleton getInstance() { if (null == instance) { //1 synchronized (Singleton.class) { if (null == instance) { //2 instance = new Singleton(); } } } return instance; } }
|
3.5 枚举
1 2 3 4
| public enum Singleton {
INSTANCE; }
|
(封面图片来源于网上,侵删)