“设计模式” 单列模式的八种写法分析
栏目:专题报道 发布时间:2022-04-19 00:03
本文摘要:前言网上泛滥流传单例模式的写法种类,有说7种的,也有说6种的,固然也不清除说5种的,他们说的有错吗?其实没有对与错,刨根问底,写法终究是写法,其本质精髓大要一致!因此完全没须要去追究写法的几多,有这个时间还不如随着宜春去网吧偷耳机、去田里抓青蛙得了,一天天的…言归正传…单例模式是最常用到的设计模式之一,熟悉设计模式的朋侪对单例模式绝对不会生疏。同时单例模式也是比力简朴易明白的一种设计模式。 文章目录何谓单例模式?

华体会体育app官网下载

前言网上泛滥流传单例模式的写法种类,有说7种的,也有说6种的,固然也不清除说5种的,他们说的有错吗?其实没有对与错,刨根问底,写法终究是写法,其本质精髓大要一致!因此完全没须要去追究写法的几多,有这个时间还不如随着宜春去网吧偷耳机、去田里抓青蛙得了,一天天的…言归正传…单例模式是最常用到的设计模式之一,熟悉设计模式的朋侪对单例模式绝对不会生疏。同时单例模式也是比力简朴易明白的一种设计模式。

文章目录何谓单例模式?单例模式的优点单例模式实现整体思路流程单例模式的适用场景单例模式的八种姿态写法姿态一:饿汉式1(静态变量)姿态二:饿汉式2(static静态代码块)姿态三:懒汉式1(线程不宁静)姿态四:懒汉式2(线程宁静)姿态五:懒汉式3 同步代码块(线程宁静)姿态六:双重检查单例姿态七:静态内部类单例姿态八:枚举JDK源码中单例模式的应用单例模式总结何谓单例模式?专业术语单例模式是一种常用的软件设计模式,其界说是单例工具的类只能允许一个实例存在。许多时候整个系统只需要拥有一个的全局工具,这样有利于我们协调系统整体的行为。好比在某个服务器法式中,该服务器的设置信息存放在一个文件中,这些设置数据由一个单例工具统一读取,然后服务历程中的其他工具再通过这个单例工具获取这些设置信息。这种方式简化了在庞大情况下的设置治理。

单例模式,简朴的说就是 一个类只能有一个实例,而且在整个项目中都能会见到这个实例。单例模式的优点1、在内存中只有一个工具,节约内存空间。2、制止频繁的建立销毁工具,可以提高性能。

3、制止对共享资源的多重占用。4、可以全局会见。单例模式实现整体思路流程首先我们要清楚单例模式要求类能够有返回工具一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称)。

单例模式的通例实现思路大致相同为以下三个步骤:1、私有结构方法2、指向自己实例的私有静态引用3、以自己实例为返回值的静态的公有的方法固然也可以明白为1、私有化结构方法,让外部不能new。2、本类内部建立工具实例【静态变量目的是为了类加载的时候建立实例】3、提供一个公有的static静态方法(一般该方法使用getInstance这个名称),返回实例工具。将该类的结构方法界说为私有方法,这样其他处的代码就无法通过挪用该类的结构方法来实例化该类的工具,只有通过该类提供的静态方法来获得该类的唯一实例;在该类内提供一个静态方法,当我们挪用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就建立该类的实例并将实例的引用赋予该类保持的引用。单例模式的适用场景由于单例模式有许多奇特的优点,所以是编程中用的比力多的一种设计模式。

我总结了一下我所知道的适合使用单例模式的场景:1、需要频繁实例化然后销毁的工具。2、建立工具时耗时过多或者耗资源过多,但又经常用到的工具。3、有状态的工具类工具。

4、频繁会见数据库或文件的工具。在后面我将会讲到JDK中的Runtime类就是使用的饿汉式单例!在Spring MVC框架中的controller 默认是单例模式的!单例模式的八种姿态写法宜春强烈建议:如果是没有接触单例模式的读者朋侪强烈建议你们动手敲一遍,不要复制,否则没效果!另有一点就是,要真正轻而易举的明白单例模式,JVM的类加载知识是不能少的,否则你只是会敲的条理,啥?不懂类加载?放心,宜春就是要你会,要你明白透彻。

别翻了,这篇文章绝对让你深刻明白java类的加载以及ClassLoader源码分析【JVM篇二】其实上面的这篇文章特别重要,上面这篇文章的重要性懂的自然懂,不懂的希望能明白宜春的一片美意,去看一下吧,实在看不懂看不下去在回来看这篇文章就好了,再大不了就把博主一起按在马桶盖盖上…是不是心里暖暖的?宜春也不多哔哔了,直接撸码走起…姿态一:饿汉式1(静态变量)package singletonPattern;//饿汉式(静态变量)class Singleton{//1、私有化结构方法,让外部不能newprivate Singleton(){ }//2、本类内部建立工具实例【静态变量目的是为了类加载的时候建立实例】private final static Singleton instance=new Singleton(); //3、提供一个公有的static静态方法,返回实例工具public static Singleton getInstance(){return instance;}}//以下是测试代码=====================public class SingletenDemo1 {public static void main(String[] args) { Singleton singleton=Singleton.getInstance(); Singleton singleton2=Singleton.getInstance();//验证一: System.out.println(singleton==singleton2);//验证二: System.out.println(singleton.hashCode()); System.out.println(singleton2.hashCode());}}//运行效果:// true// 460141958// 460141958/*饿汉式(静态变量)方法优点:写法简朴,在类加载的时候就完成了实例化,同时也就制止了线程同步问题,因此线程宁静缺点:由于是在类加载时就完成了实例化,没有到达懒加载的效果。如果一直没有使用过这个实例,就造成了内存的浪费!总结:这种方式基于ClassLoader类加载机制制止了多线程的同步问题,只不外instance属性在类加载就实例化,在单例模式中大多数都是挪用getInstance方法, 由于getInstance方法是static静态的,挪用它肯定会触发类加载!可是触发类加载的原因有许多,我们不能保证这个类会通过其他的方式触发类加载(好比挪用了其他的static方法) 这个时候初始化instance就没有到达lazy loading 懒加载的效果,可能造成内存的浪费! 饿汉式(静态变量)这种方式可以使用可是会造成内存的浪费! */123456789101112131415161718192021222324252627282930313233343536373839404142434445464748姿态二:饿汉式2(static静态代码块)package singletonPattern;//饿汉式2(static静态代码块)class Singleton2{private Singleton2(){ } private static Singleton2 instance; static{ //把建立单例工具的操作放进了static静态代码块中============== instance = new Singleton2();} public static Singleton2 getInstance(){return instance;}}//饿汉式2(static静态代码块)其实和第一种饿汉式(静态变量)方法差不多,其优缺点一致!//唯一差别的就是把建立单例工具的操作放进了static静态代码块中1234567891011121314151617181920姿态三:懒汉式1(线程不宁静)package singletonPattern;//懒汉式1(线程不宁静)class Singleton3{private Singleton3(){ } private static Singleton3 instance; public static Singleton3 getInstance(){if(instance == null){ instance=new Singleton3();}return instance;}}/*懒汉式(线程不宁静)的这种方式起到了懒加载的效果,但只能在单线程下使用。如果在多线程下,一个线程进入了if(singleton==null)判断语句块,还没执行发生实例的句子,另一个线程又进来了,这时会发生多个实例,所以不宁静。

结语:懒汉式(线程不宁静)在实际开发中,不要使用这种方式!!存在潜在危险*/1234567891011121314151617181920212223姿态四:懒汉式2(线程宁静)package singletonPattern;//懒汉式2(线程宁静)class Singleton4{private Singleton4(){ } private static Singleton4 instance; public static synchronized Singleton4 getInstance(){if(instance == null){ instance=new Singleton4();}return instance;}}/*懒汉式2(线程宁静)方式优点:线程宁静缺点:效率太低,每次挪用getInstance方法都要举行同步结语:懒汉式2(线程宁静)方式在开发中不推荐使用,主要是效率太低了*/123456789101112131415161718192021222324姿态五:懒汉式3 同步代码块(线程宁静)package singletonPattern;//懒汉式3 同步代码块(线程宁静) 可是不满足单例,在多线程下依旧会有多个实例class Singleton5{private Singleton5(){ } private static Singleton5 instance; public static Singleton5 getInstance(){if(instance == null){ //多线程情况下可能多个线程进入这个if块synchronized (Singleton5.class){ //到这里只会一个一个建立实例,虽然宁静,可是就不再是单例了 instance=new Singleton5();}}return instance;}}/*懒汉式3 同步代码块(线程宁静) 可是不满足单例,依旧会有多个实例结语:懒汉式3 同步代码块(线程宁静)方式在开发中不使用 ,实际上这个单例设计的有点搞笑*/12345678910111213141516171819202122姿态六:双重检查单例package singletonPattern;//双重检查应用实例方式class Singleton6{private Singleton6(){} private static volatile Singleton6 singleton; public static Singleton6 getInstance(){if(singleton==null){synchronized(Singleton6.class){if(singleton == null){ singleton= new Singleton6();}}}return singleton;}}/*双重检查应用实例方式:线程宁静、延迟加载、效率较高结语:开发中推荐使用!*/12345678910111213141516171819202122232425这个时候博主就得哔哔几句了,细心的童鞋会发现有一个Volatile关键字,完了,没见过,小白童鞋慌了!Volatile 变量具有 synchronized 的可见性特性,可是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。

这种实现方式既可以实现线程宁静地建立实例,而又不会对性能造成太大的影响。它只是第一次建立实例的时候同步,以后就不需要同步了,从而加速了运行速度。

华体会体育app登录入口

姿态七:静态内部类单例package singletonPattern;//static静态内部类单例class Singleton7{private Singleton7(){} private static volatile Singleton7 instance; //写一个static静态内部类,给该类添加一个static静态instance属性private static class SingletonInstance{private static final Singleton7 SINGLETON_7=new Singleton7();} //public static synchronized Singleton7 getInstence(){return SingletonInstance.SINGLETON_7;}}/*静态内部类单例方式 1、这种方式接纳了类加载机制来保证初始化实例时只有一个线程 2、巧妙的将实例化Singleton操作放进getInstance方法中,getInstance方法返回静态内部类中实例化好的Singleton 3、类的静态属性只会在第一次加载类的时候初始化,也就是只会初始化一次,在这里,JVM帮我们保证了线程的宁静,类在初始化时,此外线程无法进入。优点:线程宁静、使用静态内部类特点实现延迟加载、效率高 开发中推荐使用这种静态内部类单例方式!static静态内部特点:1、外部类加载不会导致内部类加载,保证了其懒加载*/123456789101112131415161718192021222324252627282930这个单例,宜春就不得不哔哔两句了,要清楚这个单例,必须要明确static静态内部特点,也就是外部类加载不会导致内部类加载!姿态八:枚举package singletonPattern;//使用枚举import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader;enum Singleton8{INSTANCE;public void methodName(){ System.out.println("测试数据");}}/*枚举方式的枚举:推荐写法,简朴高效。

充实使用枚举类的特性,只界说了一个实例,且枚举类是天然支持多线程的。借助JDK1.5中添加的枚举来实现单例模式优点: 1、不仅能制止多线程同步问题 2、还能防止反序列化重新建立新的工具枚举方式单例是由Effective java作者Josh Bloch提倡的,结语:推荐使用!*/123456789101112131415161718192021固然也可以测试一下public class SingletonDemo8 {public static void main(String[] args) { Singleton8 instance = Singleton8.INSTANCE; Singleton8 instance2 = Singleton8.INSTANCE; System.out.println(instance==instance2); System.out.println(instance.hashCode()); System.out.println(instance2.hashCode()); instance.methodName();}}123456789101112运行效果:true460141958460141958测试数据1234属实没毛病!JDK源码中单例模式的应用先来看一段Runtime 的源码吧,并分析一下其使用的是种单例模式!/** * Every Java application has a single instance of class * <code>Runtime</code> that allows the application to interface with * the environment in which the application is running. The current * runtime can be obtained from the <code>getRuntime</code> method. * <p> * An application cannot create its own instance of this class. * * @author unascribed * @see java.lang.Runtime#getRuntime() * @since JDK1.0 */public class Runtime {private static Runtime currentRuntime = new Runtime(); /** * Returns the runtime object associated with the current Java application. * Most of the methods of class <code>Runtime</code> are instance * methods and must be invoked with respect to the current runtime object. * * @return the <code>Runtime</code> object associated with the current * Java application. */public static Runtime getRuntime() {return currentRuntime;} /** Don't let anyone else instantiate this class */private Runtime() {}1234567891011121314151617181920212223242526272829这应该不难看出吧!如果看不出的话只能说明你真的还没有明白单例模式,我其实想说单例模式其实是23种设计模式中最简朴的一个,只是写法比力多而已!同时面试官一般都市问单例模式,它已经是很基础的了,问的稍微有点水平就是问你单例模式在JDK中那里运用到了,显然JDK中的Runtime其实它使用的就是饿汉式单例!正如注释所说,每一个java应用法式都有一个Runtime实例。Runtime的单例模式是接纳饿汉模式建立的,意思是当你加载这个类文件时,这个实例就已经存在了。

Runtime类可以取得JVM系统信息,或者使用gc()方法释放掉垃圾空间,还可以使用此类运行本机的法式。另有就是spring Mvc 中的controller 默认是单例模式的,剖析。单例模式总结1、饿汉式(静态变量)这种方式可以使用,可是没有到达 lazy loading 懒加载的效果会造成内存的浪费!开发中不建议使用。2、饿汉式(static静态代码块)其实和第一种饿汉式(静态变量)方法差不多,其优缺点一致!唯一差别的就是把建立单例工具的操作放进了static静态代码块中3、懒汉式(线程不宁静)起到了懒加载的效果,但只能在单线程下使用。

在实际开发中,不要使用这种方式!!!4、懒汉式2(线程宁静)方式线程宁静可是效率太低,每次挪用getInstance方法都要举行同步。所以在开发中不推荐使用。5、懒汉式3同步代码块(线程宁静)方式在开发中不使用 ,实际上这个设计有点搞笑哈哈。

6、双重检查应用实例方式,线程宁静、延迟加载、效率较高。因此开发中推荐使用!7、静态内部类单例方式线程宁静、使用静态内部类特点实现延迟加载、效率高。

开发中推荐使用这种静态内部类单例方式!8、借助JDK1.5中添加的枚举来实现单例模式不仅能制止多线程同步问题还能防止反序列化重新建立新的工具。枚举方式单例是由Effective java作者Josh Bloch提倡的,开发中推荐使用!单例模式必须思量到在多线程的应用场所下的使用,究竟现在的服务器基本上都是多核的了。如果本文对你有一点点资助,那么请点个赞呗,谢谢~最后,若有不足或者不正之处,接待指正品评,感谢不尽!如果有疑问接待留言,绝对第一时间回复!。


本文关键词:“,设计模式,华体会体育app下载,”,单列,模式,的,八种,写法,分析

本文来源:华体会体育app下载-www.gzxwzl.com

服务热线
0688-795932126