"double-checked locking"是否真的安全呢

本文的思想来源于:
Jeremy Manson and Brian Goetz, 《 JSR 133 (Java Memory Model) FAQ》, February 2004, http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization

"double-checked locking"经常被用于Singleton模型中实现lazy load,典型的"double-checked locking"代码如下所示:

  // double-checked-locking - don't do this!
		
		// initialization
		private static Something instance = null;
		
		public static Something getInstance() {
		  if (instance == null) {
		    synchronized (this) {
		      if (instance == null)
		        instance = new Something();
		    }
		  }
		  return instance;
		}


然后由于reordering的存在,instance 的初始化有可能会被move到getInstance之后执行。这种情况下,
虽然在getInstance()方法中,instance被正确的赋值,但是之后又被初始化为null。下面的程序打印的结果为null。

  public static Something getInstance() {
		  if (instance == null) {
		    synchronized (this) {
		      if (instance == null)
		        instance = new Something();
		    }
		  }
		  return instance;
		}
		
		private static Something instance = null;
		
		public static void main(String[] args) {
			Something instance = getInstance();
			
			System.out.println(instance);
		}


由于volatile的特性(参加另一篇文章《volatile关键词的原理与用途》),这个问题显然可以通过将instance字段声明为volatile来fix。但是更为简单直观的方法为:

  public Class LazySomething{
			// static inner class
			private static class LazySomethingHolder {
			  public static Something something = new Something();
			}
			
			public static Something getInstance() {
			  return LazySomethingHolder.something;
			}
		}

你可能感兴趣的:(java,html)