• 设计模型之单例设计


    前言

    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

    这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

    注意:1.单例类只能有一个类。2单例类必须创建自己的唯一id.

    • 3、单例类必须给所有其他对象提供这一实例。

    单例模式的实现

    单例设计模式分为两种:

    饿汉式类加载就会导致该单实例对象被创建。

    懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会被创建。

    饿汉式实现方式一:静态变量方式

    1. public class Singleton {
    2. //私有构造方法
    3. private Singleton(){
    4. }
    5. //2.在本类中创建本类对象
    6. private static Singleton instance=new Singleton();
    7. //3.提供一个公共的访问方法,让外界获取该对象
    8. public static Singleton getInstance(){
    9. return instance;
    10. }
    11. }
    1. public class Main {
    2. public static void main(String[] args) {
    3. //创建Singleton类的对象
    4. Singleton instance= Singleton.getInstance();
    5. Singleton instance1= Singleton.getInstance();
    6. System.out.println(instance==instance1);
    7. }
    8. }

     饿汉式实现方式二:静态代码块

    1. public class Singleton {
    2. //1.私有构造方法,防止被外界创建
    3. private Singleton(){};
    4. //声明Singleton类型的变量
    5. private static Singleton instance;//null
    6. //在静态代码块中进行赋值
    7. static {
    8. instance=new Singleton();
    9. }
    10. //对外界提供获取该类对象的方法
    11. public static Singleton getInstance(){
    12. return instance;
    13. }
    14. }
    1. public class Main {
    2. public static void main(String[] args) {
    3. //创建Singleton类的对象
    4. Singleton instance= Singleton.getInstance();
    5. Singleton instance1= Singleton.getInstance();
    6. System.out.println(instance==instance1);
    7. }
    8. }

     

      饿汉式实现方式三:枚举

    1. public enum Singleton {
    2. INSTANCE;
    3. }
    1. public class Main {
    2. public static void main(String[] args) {
    3. //创建Singleton类的对象
    4. Singleton instance= Singleton.INSTANCE;
    5. Singleton instance1= Singleton.INSTANCE;
    6. System.out.println(instance==instance1);
    7. }
    8. }

     

    懒汉式实现方法一:(线程不安全)

    1. public class Singleton {
    2. //1.私有构造方法,防止被外界创建
    3. private Singleton(){};
    4. //声明Singleton类型的变量,并没有进行赋值
    5. private static Singleton instance;//null
    6. //对外界提供获取该类对象的方法
    7. public static Singleton getInstance(){
    8. if(instance==null)
    9. {
    10. instance=new Singleton();
    11. }
    12. return instance;
    13. }
    14. }

    但是这种方法在多线程里是不安全的,当有两个线程时,一个线程执行到判断语句判断instance是否为null时,处于等待状态,而另一个线程获得CPU的执行权,也会进行判断里面,这时会创建两个Singleton对象。

    懒汉式实现方法二:加入synchronized 

    1. public class Singleton {
    2. //1.私有构造方法,防止被外界创建
    3. private Singleton(){};
    4. //声明Singleton类型的变量,并没有进行赋值
    5. private static Singleton instance;//null
    6. //对外界提供获取该类对象的方法
    7. public static synchronized Singleton getInstance(){
    8. if(instance==null)
    9. {
    10. instance=new Singleton();
    11. }
    12. return instance;
    13. }
    14. }

     懒汉式实现方法三:双重检查方式

    1. public class Singleton {
    2. //1.私有构造方法,防止被外界创建
    3. private Singleton(){};
    4. //声明Singleton类型的变量,并没有进行赋值
    5. private static Singleton instance;//null
    6. //对外界提供获取该类对象的方法
    7. public static Singleton getInstance(){
    8. //第一次判断,如果instance的值不为null,不需要抢占锁,直接返回对象
    9. if(instance==null)
    10. {
    11. synchronized (Singleton.class){
    12. //第二次判断
    13. if(instance==null)
    14. {
    15. instance=new Singleton();
    16. }
    17. }
    18. }
    19. return instance;
    20. }
    21. }

    双重检查锁模式的优缺点:缺点:可能会出现空指针问题。解决方法:使用volatile关键字。 volatile保证可见性和有序性。

     懒汉式实现方法四:静态内部类方式

    1. public class Singleton {
    2. //1.私有构造方法,防止被外界创建
    3. private Singleton(){};
    4. //定义一个静态内部类
    5. private static class SingletonHolder{
    6. //在内部类中声明并初始化内部类的对象
    7. private static final Singleton INSTANCE=new Singleton();
    8. }
    9. //对外界提供获取该类对象的方法
    10. public static Singleton getInstance(){
    11. return SingletonHolder.INSTANCE;
    12. }
    13. }

     静态内部类是一种优秀的单例模式,比较常用,在没有加锁的情况下,保证了多线程下的安全,并且没有任何性能影响和空间的浪费。

  • 相关阅读:
    AI学习指南数学工具篇-PCA基础知识
    第5章:程序控制结构
    博主老程序员长期个人接单
    【Verilog】HDLBits题解——Circuits/Basic Gates
    学习笔记10--ASIL分解与冗余功能安全
    【算法刷题】第一篇——哈希
    FinalReference 如何使 GC 过程变得拖拖拉拉
    IDEA Error: java: -source 1.5中不支持 lambda 表达式和 Error:java: Compilation failed
    SRM供应商管理系统有什么作用?
    俄罗斯方块游戏的设计与实现(Java+Swing+Eclipse)
  • 原文地址:https://blog.csdn.net/qq_58259539/article/details/128123876