单例模式
介绍
单例设计模式是创建型模式,是对某个类只能存在一个对象实例,并且该类提供一个获取其对象实例的方法。通常,出于节省内存资源的考虑会使用单例设计模式
分类
单例模式有八种方式:
- 饿汉式(静态常量)
- 饿汉式(静态代码块)
- 懒汉式(线程不安全)
- 懒汉式(同步方法)
- 懒汉式(同步代码块)
- 双重检查
- 静态内部类
- 枚举
1. 饿汉式(静态常量)
java
// 饿汉式(静态变量)
class Singleton {
// 构造方法私有化,不能在外部实例化
private Singleton() {
}
// 创建实例对象
private final static Singleton instance = new Singleton();
// 返回实例对象
public static Singleton getInstance() {
return instance;
}
}
优点:在类加载的时候就完成了实例化,避免了线程同步问题
缺点:没有实现懒加载
2. 饿汉式(静态代码块)
java
// 饿汉式(静态代码块)
class Singleton {
// 构造方法私有化,不能在外部实例化
private Singleton() {
}
private static Singleton instance;
// 创建实例对象
static {
instance = new Singleton();
}
// 返回实例对象
public static Singleton getInstance() {
return instance;
}
}
优点:静态代码块里面的代码在类加载时就会执行,此时已经完成了实例化,避免了线程同步问题
缺点:没有实现懒加载
3. 懒汉式(线程不安全)
java
// 懒汉式(线程不安全)
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:实现了懒加载
缺点:线程不安全。单线程的情况下可以使用
4. 懒汉式(同步方法)
java
// 懒汉式(同步方法)
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:解决了线程不安全问题
缺点:效率低,synchronized锁住了整个方法,每次访问该方法,都会锁住整个方法,但是,instance实例在第一次访问的时候就已经实例化,后续只需要直接返回,没有线程安全的问题,也就不需要每次都锁住整个方法,导致方法的效率降低
5. 懒汉式(同步代码块)
java
// 懒汉式(同步代码块)
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
}
优点:相比懒汉式(同步方法),效率有了一定的提高
缺点:线程不安全
6. 双重检查
java
// 双重检查
class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
优点:加入双重检查代码,解决线程安全问题, 同时解决懒加载问题,同时解决了效率问题
7. 静态内部类
java
// 静态内部类
class Singleton {
private Singleton() {
}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
优点:通过类加载机制解决了线程安全问题,在Singleton类被装载时并不会立即实例化,而是在需要实例化,实现了懒加载的效果
8. 枚举
java
// 枚举
enum Singleton {
INSTANCE;
public static Singleton getInstance() {
return INSTANCE;
}
}
优点:避免了线程安全问题,还能防止反序列化重新创建新的对象