?
?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
含笑半步癲 閱讀(1369)
評論(0) 編輯 收藏 引用 所屬分類:
java