单例模式(singleton)
定义
保证一个类仅有一个实例,并提供一个访问他的全局访问点。
例子
第一种方法
package com.csdhsm.pattemdesign.singleton; /** * @Title: Singleton1.java * @Description: 第一种方法,只适用于当线程,在多线程时不安全 * @author: Han * @date: 2016年6月27日 上午10:37:07 */ public class Singleton1 { private static Singleton1 singleton; public static Singleton1 getInstance() { if(singleton == null) { singleton = new Singleton1(); } return singleton; } }
第二种方法
package com.csdhsm.pattemdesign.singleton; /** * @Title: Singleton2.java * @Description: 第二种方法,在多线程下安全,但是同步锁是一个非常耗时的操作,该方法效率低 * @author: Han * @date: 2016年6月27日 上午10:39:09 */ public class Singleton2 { private static Singleton2 singleton; public static Singleton2 getInstance() { //添加同步锁,避免线程不安全 synchronized (singleton) { if(singleton == null) { singleton = new Singleton2(); } } return singleton; } }
第三种方法
package com.csdhsm.pattemdesign.singleton; /** * @Title: Singleton3.java * @Description: 第三种方法,双重if判断,一旦对象实例化之后,就不会再进入同步锁,大大提高效率,但是该代码略显复杂 * @author: Han * @date: 2016年6月27日 上午10:41:31 */ public class Singleton3 { private static Singleton3 singleton; public static Singleton3 getInstance() { if(singleton == null) { synchronized (singleton) { if(singleton == null) { singleton = new Singleton3(); } } } return singleton; } }
第四种方法
package com.csdhsm.pattemdesign.singleton; /** * @Title: Singleton4.java * @Description: 第四种方法,典型的饿汉加载,在类初始化的时候,就实例化对象,这种方法不会存在线程安全, * 但是,当类中有另外一个static方法被访问,将会引起jvm去初始化instance,最明显的 * 缺点就是如果构造器内的方法比较耗时,则加载过程会比较长。 * @author: Han * @date: 2016年6月27日 上午10:43:43 */ public class Singleton4 { private static Singleton4 singleton = new Singleton4(); public static Singleton4 getInstance() { return singleton; } }
第五种方法
package com.csdhsm.pattemdesign.singleton; /** * @Title: Singleton5.java * @Description: 第五种方法,引入一个中间容器,当调用Singleton5中的其他static方法的时候, * instance不会急着实例化,而是等使用的时候,如果SingletonHolder类没有被加载,就会去加载, * 起到延迟加载的作用,所以这种方法是懒汉单例,而且没有使用到synchronized同步块。 * @author: Han * @date: 2016年6月27日 上午10:46:38 */ public class Singleton5 { private static class SingletonHolder{ static Singleton5 singleton5 = new Singleton5(); } private Singleton5(){}; public Singleton5 getInstance(){ return SingletonHolder.singleton5; } }
总结
如果是比较简单的单例类设计,对于一般的应用,构造方法内的代码不涉及到读取配置、远程调用、初始化IOC容器等长时间执行的情况,则可以使用第四种加载方法。相反,则需要使用第五种实例方法,当使用的时候才去实例化,延缓加载。
时间: 2024-10-09 11:42:31