KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > odmg > LockingMultithreadedTest


1 package org.apache.ojb.odmg;
2
3 import org.apache.commons.lang.SystemUtils;
4 import org.apache.ojb.broker.TestHelper;
5 import org.apache.ojb.junit.JUnitExtensions;
6 import org.odmg.Database;
7 import org.odmg.Implementation;
8 import org.odmg.LockNotGrantedException;
9 import org.odmg.Transaction;
10
11 /**
12  * Test odmg-locking implementation with multiple threads.
13  * Different threads try to update the same instance / or a copy
14  * of the same object.
15  *
16  * @author <a HREF="mailto:armin@codeAuLait.de">Armin Waibel</a>
17  * @version $Id: LockingMultithreadedTest.java,v 1.3.2.2 2005/03/22 15:59:34 arminw Exp $
18  */

19 public class LockingMultithreadedTest extends JUnitExtensions.MultiThreadedTestCase
20 {
21     private static int threadCount;
22     private static Implementation odmg;
23     private static Database db;
24     private final StringBuffer JavaDoc result = new StringBuffer JavaDoc(2000);
25     private static final String JavaDoc eol = SystemUtils.LINE_SEPARATOR;
26     // number of concurrent threads to run
27
private final int concurrentThreads = 10;
28     // number of updates each thread performs against the object
29
private final int objectUpdates = 30;
30     // max number of attemps to get a lock
31
private static final int maxAttempts = 100;
32     private static final int nearMax = (int) (maxAttempts * 0.75);
33
34
35     public static void main(String JavaDoc[] args)
36     {
37         String JavaDoc[] arr = {LockingMultithreadedTest.class.getName()};
38         junit.textui.TestRunner.main(arr);
39     }
40
41     public LockingMultithreadedTest(String JavaDoc s)
42     {
43         super(s);
44     }
45
46     protected void setUp() throws Exception JavaDoc
47     {
48         super.setUp();
49     }
50
51     protected void tearDown() throws Exception JavaDoc
52     {
53         super.tearDown();
54     }
55
56     public void testLockingOfObject() throws Exception JavaDoc
57     {
58         /*
59         odmg api is threadsafe, so we can share Implementation instance
60         among the different threads
61         */

62         odmg = OJB.getInstance();
63         db = odmg.newDatabase();
64         db.open(TestHelper.DEF_DATABASE_NAME, Database.OPEN_READ_WRITE);
65
66         LockObject targetObject = createLockObjectWithRef();
67         storeObject(targetObject);
68
69         TestCaseRunnable tct [] = new TestCaseRunnable[concurrentThreads];
70         for (int i = 0; i < concurrentThreads; i++)
71         {
72             /*
73             several threads try to lock the same object (shared object),
74             the other threads lock deep copies of the shared object
75             */

76             if (i % 2 == 0)
77                 tct[i] = new LockHandle(targetObject);
78             else
79                 tct[i] = new LockHandle(targetObject.makeCopy());
80         }
81         // run test classes
82
runTestCaseRunnables(tct);
83         System.out.println("*** Result of multithreaded lock test ***");
84         System.out.println(result.toString());
85         //System.out.println(targetObject.getReference().getName());
86
}
87
88     private LockObject createLockObjectWithRef()
89     {
90         int number = newThreadKey();
91         LockObject lo = new LockObject();
92         lo.setName("modified by thread: " + number);
93
94         LockObjectRef lor = new LockObjectRef();
95         lor.setName("modified by thread: " + number);
96
97         lo.setReference(lor);
98
99         return lo;
100     }
101
102     private void storeObject(Object JavaDoc obj) throws Exception JavaDoc
103     {
104         Transaction tx = odmg.newTransaction();
105
106         tx.begin();
107         tx.lock(obj, Transaction.WRITE);
108         tx.commit();
109     }
110
111     public static synchronized int newThreadKey()
112     {
113         return threadCount++;
114     }
115
116     //=======================================================================
117
// inner classes
118
//=======================================================================
119

120     class LockHandle extends JUnitExtensions.MultiThreadedTestCase.TestCaseRunnable
121     {
122         final LockObject obj;
123         int threadNumber;
124         private int counter = 0;
125
126         public LockHandle(LockObject obj)
127         {
128             super();
129             this.obj = obj;
130         }
131
132         public void runTestCase() throws Throwable JavaDoc
133         {
134             threadNumber = newThreadKey();
135             Transaction tx = odmg.newTransaction();
136             for (int i = 0; i < objectUpdates; i++)
137             {
138                 tx.begin();
139                 updateObject(tx, obj);
140                 tx.commit();
141                 counter = 0;
142             }
143         }
144
145         private void updateObject(final Transaction tx, final LockObject obj) throws Exception JavaDoc
146         {
147             try
148             {
149                 tx.lock(obj, Transaction.WRITE);
150                 tx.lock(obj.getReference(), Transaction.WRITE);
151                 updateName(obj);
152                 updateName(obj.getReference());
153             }
154             catch (LockNotGrantedException e)
155             {
156                 if (counter < maxAttempts)
157                 {
158                     counter++;
159                     if (counter > nearMax)
160                         System.out.println("LockingMultithreadedTest: thread "
161                                 + threadNumber + " waits " + counter
162                                 + " times to update object. Maximal attempts before fail are " + maxAttempts
163                                 + ". This can be a result of low hardware.");
164                     try
165                     {
166                         Thread.sleep(30);
167                     }
168                     catch(InterruptedException JavaDoc e1)
169                     {
170                     }
171                     updateObject(tx, obj);
172                 }
173                 else
174                 {
175                     System.out.println("* Can't lock given object, will throw exception" +
176                             " for thread number " + threadNumber + " *");
177                     throw e;
178                 }
179             }
180         }
181
182         private void updateName(LockObject obj)
183         {
184             if (obj.getName().length() < 100)
185             {
186                 obj.setName(obj.getName() + "-" + threadNumber);
187             }
188             else
189             {
190                 result.append(eol).append(obj.getName());
191                 obj.setName("modified by thread: " + threadNumber);
192             }
193         }
194
195         private void updateName(LockObjectRef obj)
196         {
197             if (obj.getName().length() < 100)
198             {
199                 obj.setName(obj.getName() + "-" + threadNumber);
200             }
201             else
202             {
203                 obj.setName("modified by thread: " + threadNumber);
204             }
205         }
206     }
207
208     public static class LockObject
209     {
210         private Integer JavaDoc id;
211         private String JavaDoc name;
212         private Integer JavaDoc version;
213         private LockObjectRef reference;
214
215         public LockObject()
216         {
217         }
218
219         private LockObject(Integer JavaDoc id, String JavaDoc name, Integer JavaDoc version, LockObjectRef reference)
220         {
221             this.id = id;
222             this.name = name;
223             this.version = version;
224             this.reference = reference;
225         }
226
227         public LockObject makeCopy()
228         {
229             return new LockObject(id, name, version, reference != null ? reference.makeCopy() : null);
230         }
231
232         public Integer JavaDoc getId()
233         {
234             return id;
235         }
236
237         public void setId(Integer JavaDoc id)
238         {
239             this.id = id;
240         }
241
242         public String JavaDoc getName()
243         {
244             return name;
245         }
246
247         public void setName(String JavaDoc name)
248         {
249             this.name = name;
250         }
251
252         public Integer JavaDoc getVersion()
253         {
254             return version;
255         }
256
257         public void setVersion(Integer JavaDoc version)
258         {
259             this.version = version;
260         }
261
262         public LockObjectRef getReference()
263         {
264             return reference;
265         }
266
267         public void setReference(LockObjectRef reference)
268         {
269             this.reference = reference;
270         }
271     }
272
273     public static class LockObjectRef
274     {
275         private Integer JavaDoc id;
276         private String JavaDoc name;
277         private Integer JavaDoc version;
278
279         public LockObjectRef()
280         {
281         }
282
283         private LockObjectRef(Integer JavaDoc id, String JavaDoc name, Integer JavaDoc version)
284         {
285             this.id = id;
286             this.name = name;
287             this.version = version;
288         }
289
290         public LockObjectRef makeCopy()
291         {
292             return new LockObjectRef(id, name, version);
293         }
294
295         public Integer JavaDoc getId()
296         {
297             return id;
298         }
299
300         public void setId(Integer JavaDoc id)
301         {
302             this.id = id;
303         }
304
305         public String JavaDoc getName()
306         {
307             return name;
308         }
309
310         public void setName(String JavaDoc name)
311         {
312             this.name = name;
313         }
314
315         public Integer JavaDoc getVersion()
316         {
317             return version;
318         }
319
320         public void setVersion(Integer JavaDoc version)
321         {
322             this.version = version;
323         }
324     }
325 }
326
Popular Tags