首页 > 其他分享 >单例模式的几种实现

单例模式的几种实现

时间:2022-09-05 08:58:02浏览次数:92  
标签:Singleton getInstance private 几种 instance static 模式 单例 public

单例模式

为什么要有单例模式

实际编程应用场景中,有一些对象其实我们只需要一个,比如线程池对象、缓存、系统全局配置对象等。这样可以就保证一个在全局使用的类不被频繁地创建与销毁,节省系统资源。

注意:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其它对象提供这一实例。

1、懒汉式(线程不安全)

//使用了懒加载模式,当有多个线程并行调用getInstance()的时候,就会创建多个实例
//也就是说在多线程下不能正常工作
public class Singleton{
  private static Singleton instance;
  private Singleton(){}
  public static Singleton getInstance(){
    if(instance == null){
      instance = new Singleton();
    }
    return instance;
  }
}

2、懒汉式(线程安全,方法上加同步锁)

//实例方法上加了同步锁,保证了多线程场景下的单例,但是效率会有所折损,不过还好。
public class Singleton{
  private static Singleton singleton;
  private Singleton(){}
  public static synchronized Singleton getInstance(){
    if(singleton == null){
      singleton = new Singleton();
    }
    return singleton;
  }
}

3、饿汉式——静态常量方式(线程安全)

//类加载时就初始化实例,避免了多线程同步问题
public class Singleton{
//类加载时就初始化
  private static final Singleton instance = new Singleton;
  private Singleton(){}
  public static Singleton getInstance(){
    return instance;
  } 
}

4、饿汉式——静态代码块方式(线程安全)

//只是将类的实例化放在了静态代码块中而已,其他没区别
public class Singleton(){
  private static Singleton instance;
  static {
    instance = new Singleton();
   }
  private Singleton(){}
  public static Singleton getInstance(){
    return instance;
  }
}

5、双重校验锁(线程安全,效率高)

//不用没需要获得锁,减少了获取锁和等待的事件
public class Singleton {
  private volatile static Singleton singleton;
  private Singleton(){}
  public static Singleton getInstance(){
    if(singleton == null){
      synchronized(Singleton.class){
        if(singleton == null){
          singleton = new Singleton(); 
        }
      }
    }
    return singleton;
  }
}

6、静态内部类实现单例(线程安全,效率高)

//这种方式下 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。
注意内部类SingletonHolder要用static修饰且其中的静态变量INSTANCE必须是final的。
public class Singleton(){
  private static class SingletonHolder{
    private static final Singleton INSTANCE = new Singleton();
  }
  private Singleton(){}
  public static final Singleton getInstance(){
    return SingletonHolder.INSTANCE;
  }
}

7、枚举 Enum

public class Singleton{
  private Singleton(){}
  /*
  *枚举类型是线程安全的,并且只会装载一次
  */
  public enum SingletonEnum{
   INSTANCE;
    private finalSingleton instance;
    SingletonEnum(){
      instance = new Singleton();
    }
    private Singleton getInstance(){
      return instance;
    }
  }
  public static Singleton getInstance(){
    return SingletonEnum.INSTANCE.getInstance();
  }
}

总结:

一般情况下直接使用饿汉式就好了,如果明确要求要懒加载(lazy initialization)会倾向于使用静态内部类,如果涉及到反序列化创建对象时会试着使用枚举的方式来实现单例。

参考: https://www.cnblogs.com/happyone/p/11221157.html
https://blog.csdn.net/horizon_junmowen/article/details/108355228

标签:Singleton,getInstance,private,几种,instance,static,模式,单例,public
From: https://www.cnblogs.com/hhs-5120/p/16656831.html

相关文章

  • C# 手动终止async/await异步方法的几种实现
     终止异步方法的实现主要依靠 CancellationToken类 usingSystem;usingSystem.Net.Http;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceC......
  • 数组去重的几种方式
    1、利用Map数据结构去重1letarr=[1,2,3,4,3,2,3,4,6,7,6];2letunique=(arr)=>{3letseen=newMap();4returnarr.filter((item......
  • 工厂模式
    工厂模式简单工厂,静态工厂,工厂方法,抽象工厂,springIOC工厂定义:任何可以产生对象的方法或者类,都可以称之为工厂单例也是一种工厂不可咬文嚼字,死扣概念为什么有了new以后......
  • Singleton_单例模式:
    Singleton_单例模式:常规实现: publicclassSingleton{ privateSingleton(){ } privatefinalstaticSingletonINSTANCE=newSingleton(); publicstaticSingl......
  • 设计模式究竟是什么
    什么是设计模式?设计模式是一套由前辈总结的代码设计经验,经过反复的实践,根据这套理论,大家可以写出易维护、易拓展、复用率高的代码,经常被面向对象语言的开发者使用。Java......
  • STM32按键消抖的几种实现方式-STM32 Button Debouncing
    一、按键抖动的现象按键按下和松开的时候,按键金属片之间的贴合、分离有一个过程。给STM32输入的信号并不是理想的0和1切换的过程。而是如下图所示的,按下和松开的一小段时......
  • docker序列之网络模式
    docker网络模式用dockerrun允许docker容器时,可以使用--net选项来指定容器的网络模式,docker可以有以下4中网络模式1、host模式:使用--net=host指定host模式是和宿主......
  • 结构型模式——外观模式
    一、什么是外观模式?外观模式又名门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一的接口(你可以将其理......
  • 策略模式
    策略模式应用场景:comparator先看需求:实现一个排序器,要求可以对传入的任意类型数组都进行排序猫数组排序,狗数组排序,只要有大小关系就可以排序,而这个大小关系是我们人为......
  • 火狐浏览器f12不显示firebug开发者模式问题总结
    大家在用火狐浏览器获取页面元素的时候是不是经常用firebug开发者模式?但是我们发现一个问题,F12按下后并没有显示firebug开发者模式,检查了一下firebug和firepath插件发现都......