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
含笑半步癫 阅读(1356)
评论(0) 编辑 收藏 引用 所属分类:
java