单件模式:
确保一个类只有一个实例,并提供一个全局访问点。
目的:
备注:确保类只有一个实例并提供全局访问。全局变量可以提供全局访问,但是不能确保只有一个实例。全局变量也会变相鼓励开发人员,用许多全局变量指向许多小对象来造成命名空间的污染。
- 单件模式确保程序中一个类最多只有一个实例。
- 单件模式也提供访问这个实例的全局点。
- 在Java中实现单件模式需要私有的构造器、要给静态方法和一个静态变量。
- 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单件,以解决多线程的问题。
- 如果不是采用第五版本的Java2,双重检查锁实现会失效。
- 小心,如果使用多个类加载器,可能导致单件失效而产生多个实例。
- 如果使用JVM 1.2 或之前的版本,比必须建立单件注册表,以免垃圾收集器将单件回收。
demo:
/** * 饿汉式: * 优点:没有加任何锁,执行效率高。用户体验比懒汉式要好。 * 绝对线程,在线程没有出现以前就实例化了。 * 缺点:类加载的时候初始化,不管用不用都占着空间。 */ public class Hungry { private Hungry() { } private static final Hungry hungry = new Hungry(); public static Hungry getInstance(){ return hungry; } }
/** * 懒汉单例模式 */ public class Singleton { /** * 利用静态变量记录Singleton类的唯一实例。 */ private static Singleton uniqueInstance; /** * 私有构造器,只有来自Singleton类内才可以调用构造器 */ private Singleton() { } public static Singleton getInstance(){ //如果uniqueInstance不是null,就表示之前已经创建过对象。我们就直接跳到return语句 if (uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } }
/* @Description: 双重检查加锁 * @date 2018/4/9 21:17 */ public class SingletonDouble { //如果性能是你考虑的重点,那么这个做法可以帮你大大地奸杀getInstance()的时间耗费。 /** * volatile 关键字确保,当uniqueInstance变量被初始化成SingletonDuble实例时,多个线程正确地处理uniqueInstance * jdk 1.5以上版本才能使用volatile */ private volatile static SingletonDouble uniqueInstance; private SingletonDouble(){} public static SingletonDouble getInstance(){ //检查实例,如果不存在,就进入同步区块 if (uniqueInstance == null){ synchronized (Singleton.class){ //进入区块后再检查一次,如果任是null,才创建实例 if (uniqueInstance == null){ uniqueInstance = new SingletonDouble(); } } } return uniqueInstance; } }