随笔-30  评论-67  文章-0  trackbacks-0


 

 1 package test;
 2 
 3 public class testClone {
 4     volatile boolean isInit;
 5 
 6     volatile Foo foo;
 7 
 8     volatile int time = 1;
 9 
10     public class Foo {
11         volatile int flg;
12 
13         public Foo() {
14             flg = 0;
15             try {
16                 Thread.sleep(time);
17             } catch (InterruptedException e) {
18             }
19             ++flg;
20             System.out.println("Foo inited");
21         }
22     }
23 
24     public static void main(String[] args) throws InterruptedException {
25         testClone t = new testClone();
26         t.test();
27     }
28 
29     public void test() {
30         for (int i = 0; i < 5++i) {
31             WorkThread t = new WorkThread();
32             t.start();
33         }
34 
35         for (;;) {
36             try {
37                 Thread.sleep(1000);
38             } catch (InterruptedException e) {
39             }
40             time = 1000;
41             synchronized (this) {
42                 foo = null;
43             }
44         }
45     }
46 
47     public Foo bar() {
48         Foo f = foo;
49         if (f == null) {
50             synchronized (this) {
51                 if (foo == null) {
52                     foo = new Foo();
53                 }
54                 return foo;
55             }
56         }
57         return f;
58     }
59 
60     public class WorkThread extends Thread {
61         public void run() {
62             for (;;) {
63                 try {
64 
65                     Foo f = bar();
66                     if (f.flg == 0) {
67                         System.out.println(f.flg);
68                     }
69                 } catch (Throwable e) {
70                     e.printStackTrace();
71                 }
72             }
73         }
74     }
75 }
76 



1.4.2jdk编译执行。长时间执行没有发现有网上所说的由于jit优化导致的当分配完Foo的内存,Foo构造函数未初始化完成就将其地址赋值给foo的错误。相信这时候jit已经对代码进行了优化。

国外网址关于Double-Checked Locking的文章http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

A test case showing that it doesn't work

Paul Jakubik found an example of a use of double-checked locking that did not work correctly. A slightly cleaned up version of that code is available here.

When run on a system using the Symantec JIT, it doesn't work. In particular, the Symantec JIT compiles

singletons[i].reference = new Singleton();

to the following (note that the Symantec JIT using a handle-based object allocation system).

0206106A   mov         eax,0F97E78h
0206106F   call        01F6B210                  ; allocate space for
                                                 ; Singleton, return result in eax
02061074   mov         dword ptr [ebp],eax       ; EBP is &singletons[i].reference 
                                                ; store the unconstructed object here.
02061077   mov         ecx,dword ptr [eax]       ; dereference the handle to
                                                 ; get the raw pointer
02061079   mov         dword ptr [ecx],100h      ; Next 4 lines are
0206107F   mov         dword ptr [ecx+4],200h    ; Singleton's inlined constructor
02061086   mov         dword ptr [ecx+8],400h
0206108D   mov         dword ptr [ecx+0Ch],0F84030h

As you can see, the assignment to singletons[i].reference is performed before the constructor for Singleton is called. This is completely legal under the existing Java memory model, and also legal in C and C++ (since neither of them have a memory model).
上面是国外网站给出的jit代码和说明。


posted on 2007-01-19 14:59 含笑半步癫 阅读(1333) 评论(0)  编辑 收藏 引用 所属分类: java

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理