技术开发 频道

Java中的模式--单态

  五,证明上边的假想是可能发生的,字节码是用来分析问题的最好的工具,可以利用它来分析下边一段程序(为了分析方便,所以渐少了内容):

  字节码的使用方法见这里,利用字节码分析问题:

  class Singleton
  {
  
private static Singleton instance;
  
private boolean inUse;
  
private int val;
  
private Singleton()
  {
  inUse
= true;
  val
= 5;
  }
  
public static Singleton getInstance()
  {
  
if (instance == null)
  instance
= new Singleton();
  
return instance;
  }
  }

  得到的字节码:

  ;asm code generated for getInstance
  054D20B0 mov eax,[049388C8] ;load instance ref
  054D20B5 test eax,eax ;test
for null
  054D20B7 jne 054D20D7
  054D20B9 mov eax,14C0988h
  054D20BE call 503EF8F0 ;allocate memory
  054D20C3 mov [049388C8],eax ;store pointer in
  ;instance ref. instance
  ;non
-null and ctor
  ;has not run
  054D20C8 mov ecx,dword ptr [eax]
  054D20CA mov dword ptr [ecx],
1 ;inline ctor - inUse=true;
  054D20D0 mov dword ptr [ecx
+4],5 ;inline ctor - val=5;
  054D20D7 mov ebx,dword ptr ds:[49388C8h]
  054D20DD jmp 054D20B0
 

  上边的字节码证明,猜想是有可能实现的六:好了,上边证明Double-checked locking可能出现取出错误数据的情况,那么我们还是可以解决的:

  public static Singleton getInstance()
  {
  
if (instance == null)
  {
  
synchronized(Singleton.class) { //1
  Singleton inst
= instance; //2
  
if (inst == null)
  {
  
synchronized(Singleton.class) { //3
  inst
= new Singleton(); //4
  }
  instance
= inst; //5
  }
  }
  }
  
return instance;
  }

  利用Double-checked locking 两次同步,中间变量,解决上边的问题。

  下边这段话我只能简单的理解,翻译过来不好,所以保留原文,list 7是上边的代码,list 8是下边的。    
  The code in Listing 7 doesn't work because of the current definition of the memory model.
  The Java Language Specification (JLS) demands that code within a synchronized block not be moved out of a synchronized block. However, it does not say that code not in a synchronized block cannot be moved into a synchronized block.
  A JIT compiler would see an optimization opportunity here.
  This optimization would remove the code at //4 and the code at //5, combine it and generate the code shown in Listing 8:

  list 8

  public static Singleton getInstance()
  {
  
if (instance == null)
  {
  
synchronized(Singleton.class) { //1
  Singleton inst
= instance; //2
  
if (inst == null)
  {
  
synchronized(Singleton.class) { //3
  
//inst = new Singleton(); //4
  instance
= new Singleton();
  }
  
//instance = inst; //5
  }
  }
  }
  
return instance;
  }
0
相关文章