设计模式—单例模式

简介: 设计模式—单例模式


1.1.简介

例如在Java开发中,我们都知道类和对象实例可以通过new来创建一个或者多个,而单例模式就是采取一定的办法保证整个系统中某一个类只能存在唯一一个对象实例,并且获取该类实例的方法只能是该类自己提供的一个获取其实例的静态方法

1.2.使用样例

例如在Spring源码中的doGetBean方法中就使用到了单例模式,如下:

网络异常,图片无法展示
|

单例模式认知小结:

1.一个类只有一个实例;2.类的实例只能是由自己创建;3.该类必须向外提供获取自己实例的静态方法;

1.2.应用场景

在《图解设计模式》一书中详细介绍了单例模式在开发中的使用场景,如下所示:

一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器

1.2.代码实现

饿汉式(静态变量)

  • 类构造器私有外(防止外部使用可以new一个实例)
  • 类内部定义一个静态变量,在类的内部创建该实例
  • 提供一个静态的公共方法返回该类的实例

publicclassSingleton {

   privateSingleton() {}

   privatestaticfinalSingletonsingleton=newSingleton();

   publicstaticSingletongetInstance() {

       returnsingleton;

   }

}

Java

优点:代码实现简单,在类加载的时候就完成了类的实例化,避免了线程同步问题。

缺点:在类加载的时候完成了实例化,没有达到懒加载的效果,可能不使用到这个实例,就会造成内存浪费。

饿汉式(静态代码块)

publicclassSingleton {

   privateSingleton() {}

   privatestaticfinalSingletonsingleton;

   static {

       singleton=newSingleton();

   }

   publicstaticSingletongetInstance() {

       returnsingleton;

   }

}

Java

使用静态代码块来完成类的实例化和使用静态变量的优缺点是一样的。

懒汉式(线程不安全)

publicclassSingleton {

   privateSingleton() {}

   privatestaticSingletonsingleton;

   publicstaticSingletongetInstance() {

       if (singleton==null) {

           singleton=newSingleton();

       }

       returnsingleton;

   }

}

Java

注意:这种实现方式不推荐使用,虽然达到了懒加载的效果,但是只能在单线程下使用,在多线程下存在线程安全问题。

懒汉式(线程安全,同步方法)

publicclassSingleton {

   privateSingleton() {}

   privatestaticSingletonsingleton;

   publicstaticsynchronizedSingletongetInstance() {

       if (singleton==null) {

           singleton=newSingleton();

       }

       returnsingleton;

   }

}

Java

注意:这种实现方法也不推荐使用,虽然解决了线程安全问题,但是使用了synchronized这个庞大的东西,使得效率太低太低,每次执行getInstance()方法,都要进行方法同步。

懒汉式(线程不安全,同步代码块)

publicclassSingleton {

   privateSingleton() { }

   privatestaticSingletonsingleton;

   publicstaticSingletongetInstance() {

       if (singleton==null) {

           synchronized (Singleton.class) {

               singleton=newSingleton();

           }

       }

       returnsingleton;

   }

}

Java

注意:同步代码块的实现方式是在同步方法上改进的,因为使用同步方法使得效率很低,改为同步代码块,但是这种实现方法并不能解决线程安全问题,所以,在实际开发中不推荐使用。

双重检查(Double-check,推荐使用)

publicclassSingleton {

   privateSingleton() { }

   privatestaticvolatileSingletonsingleton=null;

   publicstaticSingletongetInstance() {

       if (singleton==null) {

           synchronized (Singleton.class) {

               if (singleton==null) {

                   singleton=newSingleton();

               }

           }

       }

       returnsingleton;

   }

}

Java

说明:线程安全、延迟加载、效率较高 、推荐使用

实例化代码只用执行一次,后面再次访问时,判断if (singleton == null), 直接return实例化对象,也避免的反复进行方法同步 。

静态内部类(线程安全,推荐使用)

publicclassSingleton {

   privateSingleton() { }

   privatestaticclassSingletonInstance {

       privatestaticfinalSingletonINSTANCE=newSingleton();

   }

   publicstaticSingletongetInstance() {

       returnSingletonInstance.INSTANCE;

   }

}

Java

  • 这种方式采用了类装载的机制来保证初始化实例时只有一个线程。
  • 静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化 时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的 实例化。
  • 类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
  • 避免了线程不安全,利用静态内部类特点实现延迟加载效率高推荐使用

枚举(推荐使用)

publicenumSingletonEnum {

   INSTANCE;

   publicvoidmethod() {

   }

}

Java

SingletonEnuminstance=SingletonEnum.INSTANCE;

Java

说明:不仅能避免多线程同步问题,而 且还能防止反序列化重新创建新的对象 ,缺点:不能懒加载。

相关文章
|
25天前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
58 0
|
1月前
|
设计模式 缓存 安全
【设计模式】单例模式:确保类只有一个实例
【设计模式】单例模式:确保类只有一个实例
20 0
|
3月前
|
设计模式 数据库连接 数据库
发挥设计模式单例模式的力量:从技术到社会的转变
发挥设计模式单例模式的力量:从技术到社会的转变
|
3月前
|
设计模式 安全 Java
设计模式-单例模式
设计模式-单例模式
36 0
|
1月前
|
设计模式 安全 Java
设计模式之单例模式
设计模式之单例模式
|
3月前
|
设计模式 缓存 安全
设计模式 - 创建型模式_ 单例模式 Singleton Pattern
设计模式 - 创建型模式_ 单例模式 Singleton Pattern
39 0
|
5天前
|
设计模式 存储 Java
Java设计模式:解释一下单例模式(Singleton Pattern)。
`Singleton Pattern`是Java中的创建型设计模式,确保类只有一个实例并提供全局访问点。它通过私有化构造函数,用静态方法返回唯一的实例。类内静态变量存储此实例,对外仅通过静态方法访问。
12 1
|
30天前
|
设计模式 存储 缓存
设计模式之单例模式(C++)
设计模式之单例模式(C++)
21 2
|
1月前
|
设计模式 安全 Java
Java设计模式之单例模式
在软件工程中,单例模式是一种常用的设计模式,其核心目标是确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。Java作为一门广泛使用的编程语言,实现单例模式是面试和实际开发中的常见需求。
66 9
Java设计模式之单例模式
|
2月前
|
设计模式 存储 安全
【设计模式】创建型模式之单例模式(Golang实现)
【2月更文挑战第3天】一个类只允许创建一个对象或实例,而且自行实例化并向整个系统提供该实例,这个类就是一个单例类,它提供全局访问的方法。这种设计模式叫单例设计模式,简称单例模式。
34 1