第一个设计模式——单例模式
创始人
2024-11-15 07:07:02
0

目录

一、特点:

二、实现单例模式步骤

三、饿汉式

四、懒汉式

五、双重检查锁

六、静态内部类

七、枚举

八、可能被反序列化和反射破坏什么意思?

九、如何解决呢?


一、特点:

  1. 唯一性,单例模式确保程序中只有一个实例存在
  2. 节省内存开销,不用多次创建对象

二、实现单例模式步骤

  1. 私有化构造函数,防止外部实例化
  2. 提供公共获取单例对象的静态方法

三、饿汉式

饿汉式是什么?

        指在类加载时就完成了初始化。

  • java实现
public class Singleton {     //创建一个静态的单例对象     private static final Singleton instance = new Singleton();      //私有化构造函数,防止外部实例化     private Singleton(){}      //提供公共的获取单例对象的静态方法     public static Singleton getInstance(){         return instance;     }  }
  • kotlin实现  
object Singleton {     //Kotlin的object关键字自动实现了饿汉式单例 }   

优点:是线程安全的,因为JVM在进行类加载的时候,会进行加锁,每个类只有一份class对象,然后类加载的时候就会执行静态代码块、静态变量。

缺点:可能被反序列化和反射破坏、浪费资源,当你不需要单例实例,只想调用类中的静态方法时,它都会帮你执行静态代码块和静态变量,因为类加载。例如:


四、懒汉式

懒汉式是什么?

        是指第一次调用时才初始化

        1.不正确的懒汉式单例模式:

        虽然最后打印的结果是一样的对象,这是只有主线程的情况,但是如果在多线程下呢?

java例子:

koltin例子:

        可以看到如果在多线程下,该对象就会被创建多次,所以这种方法是不对的。

        2.正确的懒汉式单例模式:

  • java实现
public class Singleton {     //创建一个静态的单例对象     private static Singleton instance = null;      //私有化构造函数,防止外部实例化     private Singleton(){         System.out.println("Singleton正在实例化");     }      //提供公共的获取单例对象的静态方法     public synchronized static Singleton getInstance(){         if(instance == null){             instance = new Singleton();         }         return instance;     }  }
  • kotlin 实现
class Singleton {     private constructor(){         println("Singleton正在被实例")     }      companion object{         private var instance:Singleton? = null          @Synchronized         public fun  getInstance():Singleton{             if(instance == null){                 instance = Singleton()             }             return instance!!         }     }  }

优点:在多线程下,能保证该类只实例一次。

缺点:可能被反序列化和反射破坏、为方法加锁,粒度太大,即锁定的范围过宽。这意味着锁保护的区域较大,包括了多个操作或整个方法,这会对系统的性能和并发能力产生一些负面影响,多个线程可能因为需要访问一个被锁定的方法而排队等待,导致线程资源的低效使用。

进行优化,减小锁的范围:


五、双重检查锁

  • java实现
public class Singleton {     //创建一个静态的单例对象     private volatile static Singleton instance = null;      //私有化构造函数,防止外部实例化     private Singleton(){         System.out.println("Singleton正在实例化");     }      //提供公共的获取单例对象的静态方法     public  static Singleton getInstance(){         if(instance == null){             synchronized(Singleton.class) {                 if(instance == null) {                     instance = new Singleton();                 }             }         }         return instance;     } }
  • kotlin实现
class Singleton {     private constructor(){         println("Singleton正在被实例")     }      companion object{         @Volatile         private  var instance:Singleton? = null           public fun  getInstance():Singleton{             if(instance == null){                 synchronized(Singleton::class.java) {                     if(instance == null) {                         instance = Singleton()                     }                 }             }             return instance!!         }     } }

优点:线程安全、提高了性能、避免了资源浪费。

缺点:可能被反序列化和反射破坏、结构复杂,要记得加volatile关键字。


六、静态内部类

  • java实现
public class Singleton {      //私有化构造函数,防止外部实例化     private Singleton(){         System.out.println("Singleton正在实例化");     }      // 静态内部类,只有在第一次被访问时才会被加载     private static class SingletonHolder {         private static final Singleton INSTANCE = new Singleton();     }      public static Singleton getInstance() {         return SingletonHolder.INSTANCE;     }      }
  • kotlin实现
class Singleton {     private constructor(){         println("Singleton正在被实例")     }      companion object{         object SingletonHolder{             val INSTANCE = Singleton()         }                  public fun getInstance():Singleton{             return SingletonHolder.INSTANCE         }     } }

优点:线程安全、避免了资源浪费、实现简单

 缺点:可能被反序列化和反射破坏、它的线程安全是依靠类加载,但是类加载是耗性能的,类加载的过程:


七、枚举

  • java实现
public enum Singleton {     INSTANCE;          // 可以在这里添加其他方法和属性 }
  • kotlin实现
enum class Singleton {     INSTANCE;          // 可以在这里添加其他方法和属性 }

优点:代码写法简洁优雅、线程安全(通过反编译class文件,可以看到INSTANCE是一个静态变量。那么就是通过类加载来保证线程安全的)、可以防止反序列化和反射破坏单例、并且不用手动私有化构造函数。

缺点:不能继承其它类,因为它内部已经继承了Enum类、它的线程安全是依靠类加载,但是类加载是耗性能的。


八、可能被反序列化和反射破坏什么意思?

        1.反序列化破坏:将一个单例对象进行序列化后,再反序列化,而反序列化的对象和程序对象不是同一个对象。除了枚举的单例,其它的方式都会被反序列化破坏。

        例如,以饿汉式为例子:

        2.反射破坏:通过反射调用类的无参构造函数进行创建出来对象和程序的单例对象不是同一个对象。除了枚举的单例,其它的方式都会被反射破坏

        例如,以饿汉式为例子:

        3.看看枚举的例子:

        反射创建对象,直接报错:

        序列化和反序列化不会破坏对象:


九、如何解决呢?

  • 对于序列化破坏:

  • 对于反射破坏:        

相关内容

热门资讯

安卓系统变身软件有哪些,盘点热... 你有没有发现,你的安卓手机最近是不是有点儿“焕然一新”了呢?是不是觉得它突然变得超级酷炫,仿佛拥有了...
安卓系统在欧珀手机,安卓系统下... 你有没有发现,最近欧珀手机在国内外的市场上可是越来越火了?这不,咱们就来聊聊安卓系统在欧珀手机中的应...
小米2原生安卓7系统,性能与体... 你有没有想过,一部手机,除了拍照、玩游戏,还能给你带来怎样的惊喜?今天,就让我带你走进小米2的世界,...
安卓最简单的手机系统,最简单手... 你有没有想过,拥有一部手机,却不用为复杂的系统烦恼?想象只需轻轻一点,就能完成所有操作,那该多美好!...
ros是安卓系统吗,揭秘安卓系... 哦,亲爱的读者,你是否曾好奇过,ROS(Robot Operating System)是不是安卓系统...
安卓系统装饰房子游戏,打造梦幻... 你知道吗?现在手机游戏可是越来越好玩了,尤其是那些可以在安卓系统上装饰房子的游戏,简直让人爱不释手!...
大厂攻略系统和安卓互通,解锁全... 你有没有想过,那些在大厂工作的朋友们,他们是如何轻松应对各种复杂的工作任务的呢?秘密武器之一,就是那...
amigoos是安卓系统吗,安... 你有没有听说过Amigoos这个软件?最近,它在网上可是引起了不小的讨论呢!很多人都在问,Amigo...
安卓如何弄系统配音,安卓系统配... 你有没有想过,你的安卓手机也能变得像电影里的配音演员一样,声音抑扬顿挫,引人入胜?没错,今天就要来教...
谷歌加大控制安卓系统,新策略解... 你知道吗?最近谷歌可是动作频频,对安卓系统进行了大刀阔斧的改革。这可不是小打小闹,而是要彻底改变安卓...
安卓纯净os系统就是苹果系统吗... 你有没有想过,安卓纯净OS系统是不是就像苹果系统那样呢?是不是一提到纯净,就让人联想到那简洁、优雅的...
win系统和安卓哪个好,谁更胜... 说到电脑操作系统,你是不是也跟很多人一样,在Win系统和安卓之间纠结不已?今天,就让我来给你好好分析...
安卓系统后台走流量,如何有效管... 你有没有发现,手机里的安卓系统有时候就像一个偷跑的小偷,悄无声息地在你不知情的情况下消耗着你的流量呢...
安卓系统upapp怎么更新,从... 亲爱的安卓用户们,你是否也遇到了这样的烦恼:每次打开upapp,总是发现它还停留在那个版本,而新版本...
安卓10系统的华为,创新与性能... 你知道吗?最近手机圈里可是热闹非凡呢!安卓10系统的新风潮已经吹到了华为的身上,让这款国产手机品牌焕...
安卓车机系统推介,安卓车机系统... 你有没有发现,现在开车出门,车机系统的重要性简直堪比手机里的操作系统呢!想象你正驾驶着爱车,突然想听...
安卓5.0系统我的世界,探索安... 亲爱的读者,你是否曾在某个午后,坐在电脑前,被《我的世界》那五彩斑斓的世界深深吸引?今天,就让我带你...
给安卓系统制造故障,揭秘幕后黑... 你知道吗?在科技飞速发展的今天,安卓系统已经成为了全球最受欢迎的手机操作系统之一。但是,你知道吗?有...
安卓系统怎么拍漫画,一键拍出精... 你有没有想过,用安卓手机也能轻松拍出漫画风格的图片呢?没错,就是那种色彩鲜艳、线条流畅,看起来就像是...
安卓系统的心酸史,从心酸起步到... 你有没有想过,我们每天离不开的安卓系统,它也有着一段不为人知的心酸史呢?想象一个从无到有,从默默无闻...