Java设计模式 —— 单例模式(Singleton)

单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”

定义

Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”

特征:

  • 只有一个实例对象,private构造函数
  • 提供一个公有的方法获取实例对象,static getInstance方法

代码实现

饿汉模式 —— 没有 getInstance 获取实例对象,就已经new对象,加载类的时候就构造了单例
懒汉模式 —— 在getInstance 获取实例对象使,才new对象

饿汉模式

1
2
3
4
5
6
7
8
9
10
public class Singleton {
private void Singleton() {
}

private static Singleton instance = new Singleton();

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

懒汉模式

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Singleton {
private void Singleton() {
}

private static Singleton instance;

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

单例模式使用问题

资源浪费

饿汉模式 —— 存在资源浪费问题,客户端一直不用这个对象咋办,但是饿汉模式不管,加载类就构造了单例,占用了资源。
懒汉模式就不存在资源浪费。

多线程安全问题

饿汉模式 —— 是线程安全的,加载类就构造了单例对象。
懒汉模式 —— 是线程不安全,单例对象可能null,加同步锁。

1
2
3
4
5
6
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
1
2
3
4
5
6
7
8
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

多线程性能

上面“懒汉模式”模式确实线程安全了,但是每次去执行getInstace方法都会受到同步锁的影响,运行的效率会降低

解决方法专有名词:双重锁定
Double Check Lock(DCL)

就是先判断一下

1
2
3
4
5
6
7
8
9
10
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}

一些奇葩方法:请查看Android中的设计模式之单例模式

  • 静态内部类单例模式
  • 枚举单例
  • 使用容器实现单例模式

Android中单例模式

InputMethodManager.java

xref: /frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java
在这里插入图片描述

感谢

guolin: Java设计模式透析之 —— 单例(Singleton)
segmentfault: 标签 / 单例模式 / 标签动态
百度百科: 单例模式

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×