设计模式-单例模式

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

 单例模式包括

(1)私有的构造方法

(2)含有一个该类的静态私有对象private static

(3)提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。

懒汉模式:全局的单例在第一次使用时构建(延迟初始化)

优点:
避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。
缺点:
懒汉式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。

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

饿汉模式:全局的单例实例在类装载时构建

1.线程安全
2.在类加载的同时已经创建好一个静态对象,调用时反应速度快

缺点
资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化
1
2
3
4
5
6
7
8
9
public class Singleton {
private Singleton(){
}
private static volatile Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
}

单例模式的应用

数据库连接池,多线程连接池。Windows应用管理器

优点

1.在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就 防止其它对象对自己的实例化,确保所有的对象都访问一个实例
2.单例模式具有一定的伸缩性,类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。
3.提供了对唯一实例的受控访问。
4.由于在系统内存中只存在一个对象,因此可以节约系统资源,当需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。
5.允许可变数目的实例。
6.避免对共享资源的多重占用。

缺点

单例模式可能导致内存泄漏(OOM)

1.不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
2.由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。
3.单例类的职责过重,在一定程度上违背了“单一职责原则”。
4.滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。

文章目录
  1. 1. 单例模式
    1. 1.1. 懒汉模式:全局的单例在第一次使用时构建(延迟初始化)
    2. 1.2. 饿汉模式:全局的单例实例在类装载时构建
      1. 1.2.0.0.1. 缺点
  • 1.3. 单例模式的应用
  • 1.4. 优点
  • 1.5. 缺点
  • | 139.6k