标签:设计模式
设计模式的经典模式之一——单例模式
这个也是面试经常被问起的面试,一般都要求手写
【饿汉模式】非延时加载 ——以空间换时间
【懒汉模式】延时加载——以时间换空间
看似简单,但是在懒汉模式还隐藏了一个双重检测,其中还是涉及到JVM内存的“无序写入”问题(后面使用的 volatile )
比较简单,非延时加载,一上来就把对象给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>
<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>
上面尽管这样做到了线程安全,并且解决了多实例问题,但并不高效。在任何调用这个方法的时候,你都需要承受同步带来的性能开销,然而同步只在第一次调用的时候才被需要,也就是单例类实例创建的时候。这将促使我们使用双重检查锁模式(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;// volatile 可见性/防止重排序 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及以上版本中才能正确执行。
<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>
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:设计模式
原文地址:http://blog.csdn.net/xsf50717/article/details/47305203