KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > defaults > SynchronizedComponentAdapterTestCase


1 /*****************************************************************************
2  * Copyright (C) PicoContainer Organization. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  * *
8  * Original code by *
9  *****************************************************************************/

10 package org.picocontainer.defaults;
11
12 import java.util.ArrayList JavaDoc;
13 import java.util.Collections JavaDoc;
14 import java.util.Date JavaDoc;
15 import java.util.List JavaDoc;
16
17 import junit.framework.TestCase;
18
19 import org.picocontainer.ComponentAdapter;
20 import org.picocontainer.PicoContainer;
21
22 /**
23  * @author Thomas Heller
24  * @author Aslak Hellesøy
25  * @author Jörg Schaible
26  * @version $Revision: 1572 $
27  */

28 public class SynchronizedComponentAdapterTestCase extends TestCase {
29     private Runner[] runner = new Runner[3];
30     private int blockerCounter = 0;
31
32     class Runner implements Runnable JavaDoc {
33         public RuntimeException JavaDoc exception;
34         public Blocker blocker;
35         private PicoContainer pico;
36
37         public Runner(PicoContainer pico) {
38             this.pico = pico;
39         }
40
41         public void run() {
42             try {
43                 blocker = (Blocker) pico.getComponentInstance("key");
44             } catch (RuntimeException JavaDoc e) {
45                 exception = e;
46             }
47         }
48     }
49
50     public class Blocker {
51         public Blocker() throws InterruptedException JavaDoc {
52             final Thread JavaDoc thread = Thread.currentThread();
53             synchronized (thread) {
54                 SynchronizedComponentAdapterTestCase.this.blockerCounter++;
55                 thread.wait();
56             }
57         }
58     }
59
60     private void initTest(ComponentAdapter componentAdapter) throws InterruptedException JavaDoc {
61         DefaultPicoContainer pico = new DefaultPicoContainer();
62         pico.registerComponentInstance(this);
63         pico.registerComponent(componentAdapter);
64         blockerCounter = 0;
65
66         for(int i = 0; i < runner.length; ++i) {
67             runner[i] = new Runner(pico);
68         }
69         
70         Thread JavaDoc racer[] = new Thread JavaDoc[runner.length];
71         for(int i = 0; i < racer.length; ++i) {
72             racer[i] = new Thread JavaDoc(runner[i]);
73         }
74
75         for(int i = 0; i < racer.length; ++i) {
76             racer[i].start();
77             Thread.sleep(250);
78         }
79         
80         for(int i = 0; i < racer.length; ++i) {
81             synchronized (racer[i]) {
82                 racer[i].notify();
83             }
84         }
85
86         for(int i = 0; i < racer.length; ++i) {
87             racer[i].join();
88         }
89     }
90
91     public void testRaceConditionIsHandledBySynchronizedComponentAdapter() throws InterruptedException JavaDoc {
92         ComponentAdapter componentAdapter = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter("key", Blocker.class));
93         SynchronizedComponentAdapter synchronizedComponentAdapter = new SynchronizedComponentAdapter(componentAdapter);
94         initTest(synchronizedComponentAdapter);
95
96         assertEquals(1, blockerCounter);
97         for(int i = 0; i < runner.length; ++i) {
98             assertNull(runner[i].exception);
99         }
100         for(int i = 0; i < runner.length; ++i) {
101             assertNotNull(runner[i].blocker);
102         }
103         for(int i = 1; i < runner.length; ++i) {
104             assertSame(runner[0].blocker, runner[i].blocker);
105         }
106     }
107
108     public void testRaceConditionIsNotHandledWithoutSynchronizedComponentAdapter() throws InterruptedException JavaDoc {
109         ComponentAdapter componentAdapter = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter("key", Blocker.class));
110         initTest(componentAdapter);
111
112         assertNull(runner[0].exception);
113         assertEquals(3, blockerCounter);
114         for(int i = 1; i < runner.length; ++i) {
115             assertNull(runner[i].exception);
116         }
117     }
118
119     public void THIS_NATURALLY_FAILS_testSingletonCreationRace() throws InterruptedException JavaDoc {
120         DefaultPicoContainer pico = new DefaultPicoContainer();
121         pico.registerComponentImplementation("slow", SlowCtor.class);
122         runConcurrencyTest(pico);
123     }
124
125     public void THIS_NATURALLY_FAILS_testSingletonCreationWithSynchronizedAdapter() throws InterruptedException JavaDoc {
126         DefaultPicoContainer pico = new DefaultPicoContainer();
127         pico.registerComponent(new CachingComponentAdapter(new SynchronizedComponentAdapter(new ConstructorInjectionComponentAdapter("slow", SlowCtor.class))));
128         runConcurrencyTest(pico);
129     }
130
131     // This is overkill - an outer sync adapter is enough
132
public void testSingletonCreationWithSynchronizedAdapterAndDoubleLocking() throws InterruptedException JavaDoc {
133         DefaultPicoContainer pico = new DefaultPicoContainer();
134         pico.registerComponent(new SynchronizedComponentAdapter(new CachingComponentAdapter(new SynchronizedComponentAdapter(new ConstructorInjectionComponentAdapter("slow", SlowCtor.class)))));
135         runConcurrencyTest(pico);
136     }
137
138     public void testSingletonCreationWithSynchronizedAdapterOutside() throws InterruptedException JavaDoc {
139         DefaultPicoContainer pico = new DefaultPicoContainer();
140         pico.registerComponent(new SynchronizedComponentAdapter(new CachingComponentAdapter(new ConstructorInjectionComponentAdapter("slow", SlowCtor.class))));
141         runConcurrencyTest(pico);
142     }
143
144     public void testSingletonCreationWithSynchronizedAdapterOutsideUsingFactory() throws InterruptedException JavaDoc {
145         DefaultPicoContainer pico = new DefaultPicoContainer(
146                 new SynchronizedComponentAdapterFactory(
147                         new CachingComponentAdapterFactory(
148                                 new ConstructorInjectionComponentAdapterFactory()
149                         )
150                 )
151         );
152         pico.registerComponentImplementation("slow", SlowCtor.class);
153         runConcurrencyTest(pico);
154     }
155
156     private void runConcurrencyTest(final DefaultPicoContainer pico) throws InterruptedException JavaDoc {
157         int size = 10;
158
159         Thread JavaDoc[] threads = new Thread JavaDoc[size];
160
161         final List JavaDoc out = Collections.synchronizedList(new ArrayList JavaDoc());
162
163         for (int i = 0; i < size; i++) {
164
165             threads[i] = new Thread JavaDoc(new Runnable JavaDoc() {
166                 public void run() {
167                     try {
168                         out.add(pico.getComponentInstance("slow"));
169                     } catch (Exception JavaDoc e) {
170                         // add ex? is e.equals(anotherEOfTheSameType) == true?
171
out.add(new Date JavaDoc()); // add something else to indicate miss
172
}
173                 }
174             });
175         }
176
177         for (int i = 0; i < threads.length; i++) {
178             threads[i].start();
179         }
180         for (int i = 0; i < threads.length; i++) {
181             threads[i].join();
182         }
183
184         List JavaDoc differentInstances = new ArrayList JavaDoc();
185
186         for (int i = 0; i < out.size(); i++) {
187             Object JavaDoc o = out.get(i);
188
189             if (!differentInstances.contains(o))
190                 differentInstances.add(o);
191         }
192
193         assertTrue("Only one singleton instance was created [we have " + differentInstances.size() + "]", differentInstances.size() == 1);
194     }
195
196     public static class SlowCtor {
197         public SlowCtor() throws InterruptedException JavaDoc {
198             Thread.sleep(50);
199         }
200     }
201 }
202
Popular Tags