论坛首页 编程语言技术论坛

完美的恶汉单例模式

浏览 2633 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-04-27   最后修改:2012-04-27
Author:huhang1986
Date: 2012/4/27
Email:huhang1986@126.com

延迟初始化,在程序设计中很常用。但要写出线程安全又高效的延迟初始化程序并不容易。恶汉单例模式,就是一个典型的问题。

双重检查锁定,适用场景很多,性能也不错:

import java.util.Map; 
import java.util.concurrent.ConcurrentHashMap; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

/** 
* @author xiaohanghu 
*/ 
public class DoubleCheckLock { 

private Map sotre = new ConcurrentHashMap(); 
private Lock storeLock = new ReentrantLock(); 

public Object getSingleton(String id) { 
  Object singleton = this.sotre.get(id); 

  if (null == singleton) { 
   storeLock.lock(); 
   try { 
    singleton = this.sotre.get(id); 
    if (null == singleton) { 
     singleton = createSingleton(id); 
     this.sotre.put(id, singleton); 
    } 
   } finally { 
    storeLock.unlock(); 
   } 
  } 
  return singleton; 
} 

protected Object createSingleton(String id) { 
  // TODO ... 
  return new Object(); 
} 

} 


用类加载器的方式,很巧妙:
/** 
* @author xiaohanghu 
* */ 
public class ClassLoaderLazySingleton { 

public Object getSingleton() { 
  return SingletonKeeper.singleton; 
} 

} 

class SingletonKeeper { 

// TODO ... 
static Object singleton = new Object(); 

} 

我找到一种新的办法,既保证性能又线程安全。我叫它“逻辑替换”,在第一次加锁获得单例对象后,替换程序获得单例对象的方法,改用非线程安全的方法:
/** 
* @author xiaohanghu 
* */ 
interface SingletonGetter { 

Object getSingleton(); 

} 

interface SingletonCreater { 

Object createSingleton(); 

} 

public class LazySingleton implements SingletonGetter { 

private SingletonGetter singletonGetter; 

public LazySingleton(SingletonCreater singletonCreater) { 
  singletonGetter = new OnceSingletonGetter(this, singletonCreater); 
} 

public Object getSingleton() { 
  // try { 
  // Thread.sleep(20); 
  // } catch (InterruptedException e) { 
  // e.printStackTrace(); 
  // } 
  // System.out.println(singletonGetter.getClass().getName()); 
  return singletonGetter.getSingleton(); 
} 

static class OnceSingletonGetter implements SingletonGetter { 

  private LazySingleton lazySingleton; 
  private SingletonCreater singletonCreater; 

  OnceSingletonGetter(LazySingleton lazySingleton, 
    SingletonCreater singletonCreater) { 
   this.lazySingleton = lazySingleton; 
   this.singletonCreater = singletonCreater; 
  } 

  public synchronized Object getSingleton() { 
   if (lazySingleton.singletonGetter instanceof OnceSingletonGetter) { 
    Object singletonObject = createSingleton(); 
    /** Change singletonGetter */ 
    lazySingleton.singletonGetter = new SingletonKepper( 
      singletonObject); 
    return singletonObject; 
   } 
   return lazySingleton.singletonGetter.getSingleton(); 
  } 

  private Object createSingleton() { 
   // System.out.println("#########createSingleton"); 
   return singletonCreater.createSingleton(); 
  } 
} 

static class SingletonKepper implements SingletonGetter { 

  private Object singleton; 

  SingletonKepper(Object singleton) { 
   this.singleton = singleton; 
  } 

  public Object getSingleton() { 
   return singleton; 
  } 
} 

} 
   发表时间:2012-04-30  
等待大牛回复。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics