36
36
37
37
public class SuperWaitTest {
38
38
39
- private static Semaphore mainSync = null ;
40
-
41
39
// Loads classes A and D, delegates for A's super class B
42
40
private static class MyLoaderOne extends ClassLoader {
43
41
42
+ private static boolean dIsLoading = false ;
43
+
44
44
ClassLoader parent ;
45
45
ClassLoader baseLoader ;
46
- int count ;
47
46
48
47
MyLoaderOne (ClassLoader parent ) {
49
48
this .parent = parent ;
50
49
this .baseLoader = null ;
51
- this .count = 0 ;
52
50
}
53
51
54
52
public void setBaseLoader (ClassLoader ldr ) {
@@ -61,13 +59,15 @@ public synchronized Class<?> loadClass(String name) throws ClassNotFoundExceptio
61
59
if (name .equals ("A" ) || name .equals ("D" )) {
62
60
ThreadPrint .println ("Loading " + name );
63
61
if (name .equals ("A" )) {
64
- try {
65
- ThreadPrint .println ("Waiting for " + name );
66
- mainSync .acquire (); // wait until other thread gets here
67
- wait (); // let the other thread have this lock.
68
- } catch (InterruptedException ie ) {}
62
+ ThreadPrint .println ("Waiting for " + name );
63
+ while (!dIsLoading ) { // guard against spurious wakeup
64
+ try {
65
+ wait (); // let the other thread have this lock.
66
+ } catch (InterruptedException ie ) {}
67
+ }
69
68
} else {
70
- notify (); // reacquire lock when superclass loading is done
69
+ dIsLoading = true ;
70
+ notify (); // notify lock when superclass loading is done
71
71
}
72
72
byte [] classfile = ClassUnloadCommon .getClassData (name );
73
73
return defineClass (name , classfile , 0 , classfile .length );
@@ -85,12 +85,10 @@ private static class MyLoaderTwo extends ClassLoader {
85
85
86
86
ClassLoader parent ;
87
87
ClassLoader baseLoader ;
88
- int count ;
89
88
90
89
MyLoaderTwo (ClassLoader parent ) {
91
90
this .parent = parent ;
92
91
this .baseLoader = null ;
93
- this .count = 0 ;
94
92
}
95
93
96
94
public void setBaseLoader (ClassLoader ldr ) {
@@ -102,9 +100,6 @@ public synchronized Class<?> loadClass(String name) throws ClassNotFoundExceptio
102
100
if (loadedClass != null ) return loadedClass ;
103
101
if (name .equals ("C" ) || name .equals ("B" )) {
104
102
ThreadPrint .println ("Loading " + name );
105
- if (name .equals ("C" )) {
106
- mainSync .release ();
107
- }
108
103
byte [] classfile = ClassUnloadCommon .getClassData (name );
109
104
return defineClass (name , classfile , 0 , classfile .length );
110
105
} else if (name .equals ("D" )) {
@@ -131,20 +126,21 @@ private static boolean report_success() {
131
126
132
127
public static void main (java .lang .String [] unused ) {
133
128
// t1 loads (A,CL1) extends (B,CL2); t2 loads (C,CL2) extends (D,CL1)
134
- mainSync = new Semaphore (0 );
135
129
136
130
ClassLoader appLoader = SuperWaitTest .class .getClassLoader ();
137
131
MyLoaderOne ldr1 = new MyLoaderOne (appLoader );
138
132
MyLoaderTwo ldr2 = new MyLoaderTwo (appLoader );
139
133
ldr1 .setBaseLoader (ldr2 );
140
134
ldr2 .setBaseLoader (ldr1 );
141
135
136
+ threads [0 ] = new ClassLoadingThread ("A" , ldr1 );
137
+ threads [1 ] = new ClassLoadingThread ("C" , ldr2 );
142
138
for (int i = 0 ; i < 2 ; i ++) {
143
- threads [i ] = new ClassLoadingThread (ldr1 , ldr2 , i );
144
139
threads [i ].setName ("Loading Thread #" + (i + 1 ));
145
140
threads [i ].start ();
146
141
System .out .println ("Thread " + (i + 1 ) + " was started..." );
147
142
}
143
+
148
144
if (report_success ()) {
149
145
System .out .println ("PASSED" );
150
146
} else {
0 commit comments