1.单例模式介绍二、单例模式代码演示三、总结一、单例模式介绍在系统中,一个类只能有一个实例,该类只提供一个方法(静态方法)来获取它的对象实例。说明:有时候,我们的系统只需要一个全局对象,它可以帮助我们协调系统的整体行为,节省资源。例如:1)在某个服务中,需要一个对象来读取配置文件,那么有这样一个对象来读取配置文件就可以了。2)比如我们现在要提供一个线程池,大多数情况下,像线程池这样一个重量级的对象,有几个功能模块中的一个就够了,因为它会有一个常驻的线程号,如果太多了线程池会浪费资源,所以这种对象也适用于单例。以上两种情况,都只使用了单例对象,节省了资源,简化了管理。2.用代码演示单例模式的基本实现思路。可以看出,单例模式对于一个服务只需要一个这样的对象(总是同一个对象),并且只需要一个获取实例的方法。根据这个需求,主要实现有以下两步:1)将构造方法设为private,这样其他代码就不能调用本类的构造方法,也不能使用new方法创建对象,只能提供由这个班级。静态方法获取类的唯一实例。2)在这个类中提供一个静态方法。当我们调用这个方法时,我们可以返回一个对单例对象的引用。单例模式有8种写法,1)Hungrystyle(静态常量)2)Hungrystyle(静态代码块)3)Lazystyle(线程不安全)4)Lazystyle(线程安全,同步写入)5)Lazystyle(线程安全,同步代码块)6)双重检查7)静态内部类8)枚举下面分别介绍一下每种写法:1)饿了么风格(静态常量可用)publicclassSingleton{privatestaticObjecttarget=newObject();privateSingleton(){}publicstaticObjectgetInstance(){返回目标;}}优点:写法比较简单,就是类加载的时候就已经实例化完成了。缺点:在加载类的时候就完成了初始化,没有达到懒加载的效果。如果从不使用这个实例,可能会造成内存浪费。2)饿汉式(静态代码块可用)publicclassSingleton{privatestaticObjecttarget=newObject();privateSingleton(){}publicstaticObjectgetInstance(){返回目标;}}这个方法其实和第一个类似,优缺点是一样的。3)惰性风格(线程不安全不可用)publicclassSingleton3{privatestaticObjecttarget=null;privateSingleton3(){}publicstaticObjectgetInstance(){if(target==null){target=newObject();}返回目标;}}优点:具有懒加载的效果,可以多多少少节省一些资源。缺点:只适用于单线程模式,多线程可能会创建多个单例对象,造成资源浪费。(线程A进入if判断后,时间片结束,另一个线程B也通过这条语句,然后调度线程A,继续创建另一个对象,生成多个实例。)4)惰性风格(线程安全,同步写入不推荐)publicclassSingleton4{privatestaticObjecttarget=null;privateSingleton4(){}publicstaticsynchronizedObjectgetInstance(){if(target==null){target=newObject();}返回目标;}}优点:具有懒加载的效果,线程安全。缺点:效率太低。不仅是创建的时候,每个线程想要获取实例的时候,都必须同步。实际上,它只需要在它想要一个实例的时候进行同步。如果对象已经存在,直接返回即可。5)惰性风格(线程安全,同步代码块不可用)publicclassSingleton5{privatestaticObjecttarget=null;privateSingleton5(){}publicstaticObjectgetInstance(){if(target==null){synchronized(Singleton5.class){target=newObject();}}返回目标;}}优点:优化了第四种方案,可以让获取对象的速度更快缺点:仍然存在线程安全问题,(线程A进入if判断后,时间片结束时,另一个线程B也通过这个语句,然后调度线程A,继续创建另一个对象,并生成多个实例。)6)双重检查建议使用publicclassSingleton6{privatestaticObjecttarget=null;privateSingleton6(){}publicstaticObjectgetInstance(){if(target==null){synchronized(Singleton6.class){if(target==null){target=newObject();}}}返回目标;}}优点:经过两次校验,不怕多线程同时读取。7)静态内部类推荐使用publicclassSingleton7{privatestaticclassSingletonInstance{privatestaticfinalObjecttarget=newObject();}privateSingleton7(){}publicstaticObjectgetInstance(){returnSingletonInstance.target;}}优点:类的静态属性只有在类第一次加载时才会被初始化,所以这里JVM帮我们保证了线程的安全。当类初始化时,其他线程无法进入。8)枚举推荐使用publicenumSingletonEnum{INSTANCE;publicvoiddoSomething(){System.out.println("doSomething");}}优点:保证了安全性和唯一性。缺点:所以在实际的项目开发中,很少有人这么写的。3.总结单例模式应该是设计模式中最简单的模式了。它有以下几个要素:1)私有构造方法2)私有静态引用,指向自己的实例3)以自己实例为返回值的静态公共方法至于用哪个方法获取,一般要看情况.
