1. 名称

单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类。单例模式是一种对象创建型模式。

2. 问题

在有些时候,对于某个类,我们无需创建多个它的实例。站在资源利用的角度讲,单例能够节省系统资源;站在面向对象设计的角度讲,有些类确实只应该存在一个实例。例如,一个资源管理器类(比如Windows的资源管理器),它封装着系统的一些数据信息,它的作用就是封装这些数据信息,然后提供一些操作数据的方法,供调用者调用。我们是没有必要创建出多个它的实例的(还是以Windows的资源管理器为例,正常情况下你只能打开一个它的窗口)。

3. 解决方案

实现单例模式的方案有很多,下面给出几种常见的方案:

(1) 懒汉式(线程不安全)

Java代码如下:

public class Singleton {

    private static Singleton instance;

    private Singleton() {
} public static Singleton getInstance() {
return instance == null ? new Singleton() : instance;
}
}

代码很简单,算是最基本单例模式。具有懒加载特点,即在getInstance方法调用时,才初始化instance,但其只能在单线程中达到单例效果,在多线程中可能会出现创建多个实例的问题。

(2) 懒汉式(线程安全)

Java代码如下:

public class Singleton {

    private static Singleton instance;

    private Singleton() {
} public synchronized static Singleton getInstance() {
return instance == null ? new Singleton() : instance;
}
}

由于(1)中给出的懒汉模式的getInstance方法没有同步,而达不到单例的目的,于是有了(2)中线程安全的懒汉模式。它与(1)的区别仅仅在getInstance()方法前加了synchronized关键字。但随之而来的是效率低的问题,事实上,在大部分情况下,getInstance方法是不需要同步。

(3) 饿汉式(线程安全)

Java代码如下:

public class Singleton {

    private static Singleton instance = new Singleton();

    private Singleton() {
} public synchronized static Singleton getInstance() {
return instance;
}
}

这种方式利用了classLoder的特点,在类装载时就初始化instance,而在getInstance中直接返回instance,避免了多线程安全问题。缺点是,在类装载时就实例化对象,而不能进行懒加载。

除了上面的方法外,有时候,还用静态代码块来初始化instance,与上述方法类似。

public class Singleton {

    private static Singleton instance;

    static{
instance = new Singleton();
} private Singleton() {
} public synchronized static Singleton getInstance() {
return instance;
}
}
(4) IoDH(Initialization on Demand Holder线程安全)
public class Singleton {

    private static class Holder {
private final static Singleton instance = new Singleton();
} private Singleton() {
} public synchronized static Singleton getInstance() {
return Holder.instance;
}
}

这种方式兼具了以上两种方式的优点,既能够懒加载(只有在调用getInstance方法时,系统才会装载Holder类,从而实例化Instance),又是线程安全的。

(5) 枚举
public enum Singleton {
INSTANCE;
}

利用枚举来达到单例的目的,见的比较少。

(6) 双重检查锁定(Double-check Locking线程安全)
public class Singleton {

    private static Singleton instance;

    public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

这种方法是对(2)中懒加载方式的改进。它不是将整个getInstance方法锁定,而是利用了同步代码块,缩小了同步范围,提高效率。之所以使用两层判断,原因如下:

使用第一个判断,可以避免大多数不需要同步的情况发生阻塞。如果没有该判断,与直接锁定方法无异;第二个判断是基本的判断,判断是否实例化。

最新文章

  1. 不下载SDK启动Android Studio
  2. 编程语言java-并发(锁)
  3. ORACLE--分区表数据清理
  4. 8款超绚丽的jQuery焦点图动画
  5. Openmeeting 网页打开缓慢,视频卡的一个解决方法
  6. UVA 11426 GCD-Extreme(II) ★ (欧拉函数)
  7. Java IO (2) - OutputStream
  8. CSS样式display:none和visibility:hidden的区别
  9. 两次fopen不同的文件返回相同的FILE* 地址
  10. open(),close() 打开/关闭文件
  11. 可视化之Berkeley Earth
  12. Raspberry Pi中可用的Go IDE:liteide
  13. 在后台主机中托管SignalR服务并广播心跳包
  14. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.mybatis.spring.mapper.MapperScannerConfigurer#0'
  15. 论文笔记:Rich feature hierarchies for accurate object detection and semantic segmentation
  16. Docker Kubernetes 健康检查
  17. JsonAutoDetect注解找不到错误
  18. windwos7 vnc连接centos6.6
  19. 【转载】 A* 寻路算法 (个人认为最详细,最通俗易懂的一个版本)
  20. Gym - 101806Q:QueryreuQ(回文树)

热门文章

  1. 如何一步一步用DDD设计一个电商网站(四)—— 把商品卖给用户
  2. [.NET] C# 知识回顾 - 委托 delegate (续)
  3. Xamarin+Prism开发详解二:Xaml文件如何简单绑定Resources资源文件内容
  4. ASP.NET MVC关于Ajax以及Jquery的无限级联动
  5. 从阿里巴巴笔试题看Java加载顺序
  6. linux系统维护时的一些小技巧,包括系统挂载新磁盘的方法!可收藏!
  7. SCNU ACM 2016新生赛决赛 解题报告
  8. 在 Ubuntu 14.10 中借用 Windows 的字体
  9. 利用AOP写2PC框架(一)
  10. RabbitMQ的安装过程