单例模式是非常好理解的设计模式,但也包含了很多细节。
一、什么是单例模式?
单例模式的定义
1.1、基本定义
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
- 单例类在内存中只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
-
1.2、Java 中单例模式的特点
在一个JVM中,只存在一个实例。
- 构造器必须是私有的,外部类无法通过调用构造器方法创建该实例。
- 没有公开的创建对象的方法。
- 提供一个公开的静态方法获取 JVM 中的唯一实例。
二、代码实现
几种实现单例模式的方式
2.1、饿汉式
这个人很饿,所以他管不了那么多了,项目一启动直接创建一个对象塞到 JVM 里。
2.1.1、伪代码
2.1.2、代码实现
public class SingleObject {
//第一步:私有化构造函数。
private SingleObject(){}
//第二步:调用私有化的构造函数创建一个对象,并将其赋值给一个私有的静态变量。
private static SingleObject instance = new SingleObject();
//第三步:创建一个静态方法以访问 JVM 中的唯一实例。
//静态方法不属于具体某一个对象,属于类的层次。
public static SingleObject getInstance(){
return instance;
}
//该方法仅是一个普通方法
public void showMessage(){
System.out.println("Hello World!");
}
}
2.2、懒汉式
2.2.1、伪代码
2.2.2、代码实现
public class Singleton {
private volatile static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
//先检查实例是否存在,如果不存在才进入下面的同步块
if(instance == null){
//同步块,线程安全的创建实例
synchronized (Singleton.class) {
//再次检查实例是否存在,如果不存在才真正的创建实例
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
2.3、静态内部类实现单例模式
简单
使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance()
的时候,JVM 能够帮我们保证 instance 只被创建一次,并且会保证把赋值给 instance 的内存初始化完毕, 这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。这是一个比较完美的单例模式。
public class Singleton {
/* 私有构造方法,防止被实例化 */
private Singleton() {
}
/* 此处使用一个内部类来维护单例 */
private static class SingletonFactory {
private static Singleton instance = new Singleton();
}
/* 获取实例 */
public static Singleton getInstance() {
return SingletonFactory.instance;
}
/* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
public Object readResolve() {
return getInstance();
}
}
2.4、通过枚举类的特性实现单例模式
使用枚举来实现单实例控制会更加简洁,而且 JVM 从根本上提供保障,绝对防止多次实例化,是更简洁、高效、安全的实现单例的方式。
class Resource{
}
public enum SomeThing {
INSTANCE;
private Resource instance;
SomeThing() {
instance = new Resource();
}
public Resource getInstance() {
return instance;
}
}