Fork me on Gitee

单例设计模式singleton

简单引入

单例设计模式作为最简单,最常用的设计模式。一般是这两中写法,这两种写法教科书所谓的标准写法,但是实际上存在不少问题。后面介绍标准写法,以规避这些问题。

1.懒汉式:


/**
	 * 问题在于,当多线程工作的时候,如果有多个线程同时运行到if (instance ==
	 * null),都判断为null,那么两个线程就各自会创建一个实例——这样一来,就不是单例了。
	 */
class Singleton {

	private Singleton() {
	};

	private static Singleton s;

	public static Singleton getInstance() {
		if (s == null) {
			s = new Singleton();
		}
		return s;
	}

}

2.恶汉式

class Singleton {
	private Singleton() {
	}

	private static Singleton singleton = new Singleton();

	public static Singleton getInstance() {
		return singleton;
	}

}

标准写法

改变懒汉式1.

(规避线程安全问题)加上 synchronized修饰方法即可

class Singleton {

	private Singleton() {
	};

	private static Singleton s;

	public static synchronized Singleton getInstance() {
		if (s == null) {
			s = new Singleton();
		}
		return s;
	}

}

改变懒汉式2. 双重检查 Double-Check』写法

1.第一个if 只有instance为null的时候,才进入synchronized的代码段——大大减少了几率。
2.第二个if 是为了防止可能出现多个实例的情况。

 class DoubleCheck {

	private DoubleCheck() {
	}

	private static DoubleCheck dCheck;

	public static DoubleCheck getInstance() {
		if (dCheck == null) {
			synchronized (DoubleCheck.class) {
				if (dCheck == null) {
					dCheck = new DoubleCheck();
				}
			}
		}
		return dCheck;
	}

}

改变懒汉式2.之终极版 防止指令重排列 volatile

不知道原子操作,与指令重排的建议复习下

 class DoubleCheck2 {
	private DoubleCheck2() {
	}

	private static volatile DoubleCheck2 sCheck;

	public static DoubleCheck2 getInstance() {
		if (sCheck == null) {
			synchronized (DoubleCheck2.class) {
				if (sCheck == null) {
					sCheck = new DoubleCheck2();
				}
			}
		}
		return sCheck;
	}

}

1.恶汉式:

说白了,有classloder装载 就是一开始就创建类

/*
	 * 缺点也就只是饿汉式单例本身的缺点所在了——由于INSTANCE的初始化是在类加载时进行的,而类的加载是由ClassLoader来做的,
	 * 所以开发者本来对于它初始化的时机就很难去准确把握:
	 * 
	 * 可能由于初始化的太早,造成资源的浪费 如果初始化本身依赖于一些其他数据,那么也就很难保证其他数据会在它初始化之前准备好。
	 */
class Singleton {
	private Singleton() {
	}

	private static final Singleton singleton = new Singleton();

	public static Singleton getInstance() {
		return singleton;
	}

}

由于静态内部类实现

class innerSingleton {
	private innerSingleton() {

	}

	private static class SingletonHolder {
		private static final innerSingleton SINGLETON = new innerSingleton();
	}

	public static innerSingleton getInstance() {
		return SingletonHolder.SINGLETON;
	}

}
posted @ 2018-05-30 23:17  ---dgw博客  阅读(245)  评论(0编辑  收藏  举报