设计模式—单例模式

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

设计模式—单例模式

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

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

相关文章
|
3月前
|
设计模式 安全 Java
C# 一分钟浅谈:设计模式之单例模式
【10月更文挑战第9天】单例模式是软件开发中最常用的设计模式之一,旨在确保一个类只有一个实例,并提供一个全局访问点。本文介绍了单例模式的基本概念、实现方式(包括饿汉式、懒汉式和使用 `Lazy<T>` 的方法)、常见问题(如多线程和序列化问题)及其解决方案,并通过代码示例详细说明了这些内容。希望本文能帮助你在实际开发中更好地应用单例模式,提高代码质量和可维护性。
82 1
|
设计模式 安全 Java
设计模式~~~单例模式
设计模式~~~单例模式
46 0
|
6月前
|
设计模式 安全 C++
C++一分钟之-C++中的设计模式:单例模式
【7月更文挑战第13天】单例模式确保类只有一个实例,提供全局访问。C++中的实现涉及线程安全和生命周期管理。基础实现使用静态成员,但在多线程环境下可能导致多个实例。为解决此问题,采用双重检查锁定和`std::mutex`保证安全。使用`std::unique_ptr`管理生命周期,防止析构异常和内存泄漏。理解和正确应用单例模式能提升软件的效率与可维护性。
71 2
|
设计模式 安全 Java
23中设计模式之单例模式
23中设计模式之单例模式
40 1
|
设计模式 安全 Java
【3W2H设计模式】单例模式
【3W2H设计模式】单例模式
145 0
|
设计模式 SQL 存储
设计模式——单例模式详解
设计模式——单例模式详解
|
设计模式 安全 Java
【设计模式】单例模式
【设计模式】单例模式
|
设计模式 安全 Java
23种设计模式——单例模式
单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
72 0
23种设计模式——单例模式
|
设计模式 安全 Java
设计模式-12-单例模式
单例模式(Singleton Pattern)负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。也属于创建型模式。
66 0
|
设计模式 安全 C#
【设计模式】C#实现单例模式
单例模式:某一个类在系统中只需要有一个实例对象,而且对象是由这个类自行实例化并提供给系统其它地方使用。单例模式属于一种创建型设计模式。