单例模式
Published in:2023-10-10 | category: 学习

单例模式(Singleton)是一种创建对象的设计模式,确保在应用程序中只有一个实例。

优点:

1、确保一个类只有一个实例,避免了重复创建对象的开销。

2、提供全局访问点,方便在整个程序中访问该实例。

3、可以控制对象的数量和生命周期,确保对象的一致性和可靠性。

4、可以避免多线程冲突问题,在多线程环境下保证对象的唯一性。

缺点:

1、单例模式可能导致紧耦合,使得程序的扩展性和可维护性变差。

2、单例模式不适合需要多个相互独立的实例的情况,违背了单一职责原则。

3、单例模式的实现需要考虑线程安全,增加了实现的复杂性。

五种实现方式:

饿汉式:没有实现懒加载,在类加载时初始化,即在运行之前只是将打包的代码加载到内存的时候就初始化,会造成内存浪费,但是它线程安全,并且执行效率高。

1
2
3
4
5
6
7
8
9
10
11
public class Singleton {

private static final Singleton singleton = new Singleton();

private Singleton() {}

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

懒汉式:单例对象被使用的时候才初始化,避免了内存浪费。占用空间小,效率有问题,线程不安全。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Singleton{
private static Singleton singleton;

private Singleton() { //私有构造
}

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

当多个对象进入getInstance()方法中的if时被判断为空,可能创建多个实例对象。

解决办法:

可以在方法上加上synchronized同步锁,但是运行效率低下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {

private static Singleton singleton;

private Singleton() {}

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

双重检查锁:提高了同步锁的效率,使用双重检查锁进一步进行优化,可以避免整个方法被锁,只对需要锁的代码部分进行加锁,可以提高执行效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Singleton {

private static volatile Singleton singleton;

private Singleton() {}

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

静态内部类:引入一个静态内部类,静态内部类只有在调用的时候才会加载,保证了Singleton实例的延迟初始化,又保证了实例的唯一性。

静态内部类虽然保证了单例在多线程并发下的线程安全性,但是在遇到序列化对象时吗,默认的方式运行得到的结果就是多例的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {

private Singleton() {
}

private static class InnerObject {
private static Singleton singleton = new Singleton();
}

public static synchronized Singleton getInstance() {
return InnerObject.singleton;
}
}

内部枚举类:防止了反射和序列化攻击。通过Java反射机制可以实例化构造方法为private的类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class SingletonFactory {

private enum EnumSingleton {
SINGLETON;
private Singleton singleton;
//枚举类的构造方法在类加载被实例化
private EnumSingleton() {
singleton = new Singleton();
}

public Singleton getInstance() {
return singleton;
}
}

public static Singleton getInstance() {
return EnumSingleton.SINGLETON.getInstance();
}
}

class Singleton{
public Singleton() {
}
}
Prev:
滑动窗口
Next:
Jsp内置对象