设计模式的经典模式之一——单例模式
这个也是面试经常被问起的面试,一般都要求手写
【饿汉模式】非延时加载 ——以空间换时间
【懒汉模式】延时加载——以时间换空间
看似简单,但是在懒汉模式还隐藏了一个双重检测,其中还是涉及到JVM内存的“无序写入”问题(后面使用的 volatile )
1、饿汉模式
比较简单,非延时加载,一上来就把对象给new出来了
- <span style="font-family:Microsoft YaHei;font-size:14px;">public class Singleton {
- private Singleton(){}
- private static Singleton instance = new Singleton();
- public Singleton getIntance(){
- return instance;
- }
- }</span>
2、懒汉模式,延时加载
【1】普通
- <span style="font-family:Microsoft YaHei;font-size:14px;">public class Singleton {
- private Singleton() { }
-
- private static Singleton instance = null;
-
- public static synchronized Singleton getIntance() {
- if (instance == null) {
- instance = new Singleton();
- }
- return instance;
- }
-
- }</span>
【2】双重检测(有缺陷来自JVM自身)
上面尽管这样做到了线程安全,并且解决了多实例问题,但并不高效。在任何调用这个方法的时候,你都需要承受同步带来的性能开销,然而同步只在第一次调用的时候才被需要,也就是单例类实例创建的时候。这将促使我们使用双重检查锁模式(double checked locking pattern),一种只在临界区代码加锁的方法。一般称其为双重检查锁,因为会有两次检查 _instance == null,一次不加锁,另一次在同步块上加锁。
- <span style="font-family:Microsoft YaHei;font-size:14px;">public class Singleton {
- private Singleton() { }
-
- private volatile static Singleton instance = null;
-
- public static Singleton getIntance() {
-
- if (instance == null) {
-
- synchronized (Singleton.class) {
-
- if (instance == null) {
- instance = new Singleton();
- }
-
- }
-
- }
- return instance;
- }
-
- }</span>
如果使用双重检查锁定来实现懒汉式单例类,需要在静态成员变量instance之前增加修饰符volatile(可见性,防止重排序),被volatile修饰的成员变量可以确保多个线程都能够正确处理,且该代码只能在JDK 1.5及以上版本中才能正确执行。
【3】ThreadLocal模式的单例
- <span style="font-family:Microsoft YaHei;font-size:14px;"> public class Singleton{
- public static final ThreadLocal threadInstance=new ThreadLocal();
- public static Singleton singleton=null;
- public static getSingleton(){
- if(threadInstance.get()==null){
- createSingleton();
- }
- }
- public static Singleton createSingleton(){
- synchronized(Singleton.class){
- if(singleton==null){
- singleton=new Singleton();
- }
- }
- }
-
- } </span>
ThreadLocal的全局变量局部化 第一次检测采用线程局部来做如果线程已经访问过则不需要进入同步块
转载:http://blog.csdn.net/xsf50717/article/details/47305203