KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javolution > context > ConcurrentContext


1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2006 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package javolution.context;
10
11 import j2me.lang.ThreadLocal;
12 import j2me.lang.UnsupportedOperationException;
13
14 import javolution.context.ConcurrentExecutor.Status;
15 import javolution.lang.Configurable;
16 import javolution.lang.Reflection;
17
18 /**
19  * <p> This class represents a concurrent context; it is used to accelerate
20  * execution of concurrent algorithms on multi-processors systems.</p>
21  *
22  * <p> When a thread enters a concurrent context, it may execute multiple
23  * concurrent {@link Logic logics} by calling any of the
24  * <code>ConcurrentContext.execute(logic, arg0, arg1, ...)</code>
25  * static methods. The logic is then executed at the same priority
26  * as the current thread and in the same memory area by a
27  * {@link ConcurrentThread} or by the current thread itself if there is
28  * no concurrent thread immediately available (as the number of concurrent
29  * threads is limited, see
30  * <a HREF="{@docRoot}/overview-summary.html#configuration">
31  * Javolution Configuration</a> for details).</p>
32  *
33  * <p> Only after all concurrent executions are completed, is the current
34  * thread allowed to exit the scope of the concurrent context
35  * (internal synchronization).</p>
36  *
37  * <p> Concurrent logics always execute within the same {@link Context} as
38  * the calling thread, in other words if the main thread runs in a
39  * {@link PoolContext}, concurrent executions are performed in the
40  * same {@link PoolContext} as well.</p>
41  *
42  * <p> Concurrent contexts are easy to use, and provide automatic
43  * load-balancing between processors with almost no overhead. Here is
44  * an example of <b>concurrent/recursive/clean</b> implementation of the
45  * Karatsuba multiplication for large integers:[code]
46  * import javolution.context.PoolContext.Reference;
47  * ...
48  * public LargeInteger multiply(LargeInteger that) {
49  * if (that._size <= 1) {
50  * return multiply(that.longValue()); // Direct multiplication.
51  *
52  * } else { // Karatsuba multiplication in O(n^log2(3))
53  * PoolContext.enter(); // Avoids generating garbage (also faster).
54  * try {
55  * int bitLength = this.bitLength();
56  * int n = (bitLength >> 1) + (bitLength & 1);
57  *
58  * // this = a + 2^n b, that = c + 2^n d
59  * LargeInteger b = this.shiftRight(n);
60  * LargeInteger a = this.minus(b.shiftLeft(n));
61  * LargeInteger d = that.shiftRight(n);
62  * LargeInteger c = that.minus(d.shiftLeft(n));
63  * Reference<LargeInteger> ac = Reference.newInstance();
64  * Reference<LargeInteger> bd = Reference.newInstance();
65  * Reference<LargeInteger> abcd = Reference.newInstance();
66  * ConcurrentContext.enter();
67  * try {
68  * ConcurrentContext.execute(MULTIPLY, a, c, ac);
69  * ConcurrentContext.execute(MULTIPLY, b, d, bd);
70  * ConcurrentContext.execute(MULTIPLY, a.plus(b), c.plus(d), abcd);
71  * } finally {
72  * ConcurrentContext.exit(); // Waits for all concurrent threads to complete.
73  * }
74  *
75  * // a*c + ((a+b)*(c+d)-a*c-b*d) 2^n + b*d 2^2n
76  * LargeInteger product = ac.get().plus(abcd.get().minus(ac.get()).minus(bd.get()).shiftLeft(n)).plus(bd.get().shiftLeft(2 * n));
77  * return product.export();
78  * } finally {
79  * PoolContext.exit();
80  * }
81  * }
82  * }
83  * private static final Logic MULTIPLY = new Logic() {
84  * public void run() {
85  * LargeInteger left = getArgument(0);
86  * LargeInteger right = getArgument(1);
87  * Reference<LargeInteger> result = getArgument(2);
88  * result.set(left.times(right)); // Recursive.
89  * }
90  * };[/code]
91  *
92  * Here is a concurrent/recursive quick/merge sort using anonymous inner
93  * classes (same as in Javolution
94  * <a HREF="http://javolution.org/doc/benchmark.html">benchmark</a>):[code]
95  * private void quickSort(final FastTable<? extends Comparable> table) {
96  * final int size = table.size();
97  * if (size < 100) {
98  * table.sort(); // Direct quick sort.
99  * } else {
100  * // Splits table in two and sort both part concurrently.
101  * final FastTable<? extends Comparable> t1 = FastTable.newInstance();
102  * final FastTable<? extends Comparable> t2 = FastTable.newInstance();
103  * ConcurrentContext.enter();
104  * try {
105  * ConcurrentContext.execute(new Logic() {
106  * public void run() {
107  * t1.addAll(table.subList(0, size / 2));
108  * quickSort(t1); // Recursive.
109  * }
110  * });
111  * ConcurrentContext.execute(new Logic() {
112  * public void run() {
113  * t2.addAll(table.subList(size / 2, size));
114  * quickSort(t2); // Recursive.
115  * }
116  * });
117  * } finally {
118  * ConcurrentContext.exit();
119  * }
120  * // Merges results.
121  * for (int i=0, i1=0, i2=0; i < size; i++) {
122  * if (i1 >= t1.size()) {
123  * table.set(i, t2.get(i2++));
124  * } else if (i2 >= t2.size()) {
125  * table.set(i, t1.get(i1++));
126  * } else {
127  * Comparable o1 = t1.get(i1);
128  * Comparable o2 = t2.get(i2);
129  * if (o1.compareTo(o2) < 0) {
130  * table.set(i, o1);
131  * i1++;
132  * } else {
133  * table.set(i, o2);
134  * i2++;
135  * }
136  * }
137  * }
138  * FastTable.recycle(t1);
139  * FastTable.recycle(t2);
140  * }
141  * }[/code]
142  *
143  * <p> Finally, it should be noted that concurrent contexts ensure the same
144  * behavior whether or not the execution is performed by the current
145  * thread or concurrent threads. In particular, the current {@link Context
146  * context} is inherited by concurrent threads and any exception raised
147  * during the concurrent logic executions is automatically propagated
148  * to the current thread.</p>
149  *
150  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
151  * @version 4.1, December 1, 2006
152  */

153 public class ConcurrentContext extends Context {
154
155     /**
156      * Holds the context factory.
157      */

158     private static Factory FACTORY = new Factory() {
159         protected Object JavaDoc create() {
160             return new ConcurrentContext();
161         }
162     };
163
164     /**
165      * Holds the default number of {@link ConcurrentExecutor concurrent
166      * executors} (see <a HREF="{@docRoot}/overview-summary.html#configuration">
167      * Javolution Configuration</a> for details).
168      */

169     public static final Configurable/*<Integer>*/CONCURRENCY = new Configurable(
170             concurrency());
171
172     /**
173      * Indicates if local concurrency is enabled.
174      */

175     private static final LocalContext.Reference ENABLED = new LocalContext.Reference(
176             new Boolean JavaDoc(true));
177
178     /**
179      * Holds the thread-local arguments.
180      */

181     private static final ThreadLocal JavaDoc ARGUMENTS = new ThreadLocal JavaDoc();
182
183     /**
184      * Holds the class object (cannot use .class with j2me).
185      */

186     private static final Class JavaDoc CLASS = new ConcurrentContext().getClass();
187
188     /**
189      * Holds the default executors.
190      */

191     private static transient ConcurrentExecutor[] _DefaultExecutors;
192
193     /**
194      * Holds the number of concurrent thread initiated (might not have
195      * started yet).
196      */

197     private int _initiatedCount;
198
199     /**
200      * Holds the number of concurrent thread execution completed.
201      */

202     private int _completedCount;
203
204     /**
205      * Holds any error occuring during concurrent execution.
206      */

207     private Throwable JavaDoc _error;
208
209     /**
210      * Holds this context executors or <code>null</code> to inherit
211      * concurrent executors from outer concurrent context.
212      */

213     private ConcurrentExecutor[] _executors;
214
215     /**
216      * Indicates if this context is enabled.
217      */

218     private boolean _isEnabled;
219
220     /**
221      * Holds the inherited exectors.
222      */

223     private ConcurrentExecutor[] _inheritedExecutors;
224
225     /**
226      * Creates a concurrent context inheriting its executors from
227      * the outer concurrent context (or the {@link #getDefaultExecutors() default
228      * executors} if none).
229      */

230     public ConcurrentContext() {
231         this(null);
232     }
233
234     /**
235      * Creates a concurrent context using the specified concurrent executors.
236      *
237      * @param executors the concurrent executors available for dispatching.
238      */

239     public ConcurrentContext(ConcurrentExecutor[] executors) {
240         _executors = executors;
241     }
242
243     /**
244      * Returns the default executors. The number of executors is configurable
245      * (see <a HREF=
246      * "{@docRoot}/overview-summary.html#configuration">Javolution Configuration
247      * </a> for details).
248      *
249      * @return the default concurrent executors.
250      */

251     public static ConcurrentExecutor[] getDefaultExecutors() {
252         if (_DefaultExecutors != null)
253             return _DefaultExecutors;
254         synchronized (CLASS) { // Creates the default.
255
if (_DefaultExecutors != null)
256                 return _DefaultExecutors; // Synchronized check.
257
int concurrency = ((Integer JavaDoc) CONCURRENCY.get()).intValue();
258             ConcurrentThread[] executors = new ConcurrentThread[concurrency];
259             for (int i = 0; i < concurrency; i++) {
260                 executors[i] = new ConcurrentThread();
261                 executors[i].start();
262             }
263             _DefaultExecutors = executors;
264             return _DefaultExecutors;
265         }
266     }
267
268     /**
269      * Sets the default concurrent executors.
270      *
271      * @param executors the new default concurrent executors.
272      */

273     public static void setDefaultExecutors(ConcurrentExecutor[] executors) {
274         _DefaultExecutors = executors;
275     }
276
277     /**
278      * Returns the concurrent executors available to this concurrent
279      * context (inherited from outer concurrent contexts).
280      *
281      * @return the concurrent executors available to this context.
282      */

283     final ConcurrentExecutor[] getExecutors() {
284         if (_executors != null)
285             return _executors;
286         for (Context ctx = this.getOuter(); ctx != null; ctx = ctx.getOuter()) {
287             if (ctx instanceof ConcurrentContext) {
288                 ConcurrentContext that = (ConcurrentContext) ctx;
289                 if (that._executors != null)
290                     return that._executors;
291             }
292         }
293         return getDefaultExecutors();
294     }
295
296     /**
297      * Terminates the executors for this concurrent context (if any).
298      */

299     public void clear() {
300         if (_executors != null) {
301             for (int i = 0; i < _executors.length; i++) {
302                 _executors[i].terminate();
303             }
304             _executors = null;
305         }
306     }
307
308     /**
309      * Returns the current concurrent context or <code>null</code> if the
310      * current thread has not been spawned from a concurrent context.
311      *
312      * @return the current concurrent context.
313      */

314     public static/*ConcurrentContext*/Context current() {
315         Context ctx = Context.current();
316         while (ctx != null) {
317             if (ctx instanceof ConcurrentContext)
318                 return (ConcurrentContext) ctx;
319             ctx = ctx.getOuter();
320         }
321         return null;
322     }
323
324     /**
325      * Enters a {@link ConcurrentContext} possibly recycled.
326      * The new concurrent context is enabled/disabled based upon
327      * the local {@link #isEnabled()} status.
328      */

329     public static void enter() {
330         ConcurrentContext ctx = (ConcurrentContext) FACTORY.object();
331         ctx._isInternal = true;
332         ctx._isEnabled = ConcurrentContext.isEnabled();
333         Context.enter(ctx);
334     }
335
336     private transient boolean _isInternal;
337
338     /**
339      * Exits and recycles the current {@link ConcurrentContext}.
340      *
341      * @throws UnsupportedOperationException if the current context
342      * has not been entered using ConcurrentContext.enter()
343      */

344     public static void exit() {
345         ConcurrentContext ctx = (ConcurrentContext) Context.current();
346         if (!ctx._isInternal)
347             throw new UnsupportedOperationException JavaDoc(
348                     "The context to exit must be specified");
349         ctx._isInternal = false;
350         Context.exitNoCheck(ctx);
351         FACTORY.recycle(ctx);
352     }
353
354     /**
355      * Enables/disables {@link LocalContext local} concurrency.
356      *
357      * @param enabled <code>true</code> if concurrency is locally enabled;
358      * <code>false</code> otherwise.
359      * @see #enter
360      */

361     public static void setEnabled(boolean enabled) {
362         ENABLED.set(enabled ? TRUE : FALSE);
363     }
364
365     private static final Boolean JavaDoc TRUE = new Boolean JavaDoc(true); // CLDC 1.0
366

367     private static final Boolean JavaDoc FALSE = new Boolean JavaDoc(false); // CLDC 1.0
368

369     /**
370      * Indicates if concurrency is {@link LocalContext locally} enabled
371      * (default <code>true</code>).
372      *
373      * @return <code>true</code> if concurrency is locally enabled;
374      * <code>false</code> otherwise.
375      * @see #enter
376      */

377     public static boolean isEnabled() {
378         return ((Boolean JavaDoc) ENABLED.get()).booleanValue();
379     }
380
381     /**
382      * Executes the specified logic by a {@link ConcurrentExecutor} if
383      * one available. Any exception or error during execution is propagated
384      * to the current thread upon {@link #exit} of the concurrent context.
385      *
386      * @param logic the logic to execute concurrently when possible.
387      * @throws ClassCastException if the current context is not a
388      * {@link ConcurrentContext}.
389      */

390     public static void execute(Logic logic) {
391         ConcurrentContext ctx = (ConcurrentContext) current();
392         
393         StatusImpl status = (StatusImpl) StatusImpl.FACTORY.object();
394         status._args = status._args0;
395  
396         if ((ctx != null) && (ctx.doExecute(logic, status)))
397                 return; // Concurrent execution.
398
// Else current thread execution.
399
ARGUMENTS.set(status._args);
400         logic.run();
401         StatusImpl.FACTORY.recycle(status);
402     }
403
404     /**
405      * Executes the specified logic with the specified argument.
406      *
407      * @param logic the logic to execute concurrently when possible.
408      * @param arg0 the logic argument.
409      * @throws ClassCastException if the current context is not a
410      * {@link ConcurrentContext}.
411      */

412     public static void execute(Logic logic, Object JavaDoc arg0) {
413         ConcurrentContext ctx = (ConcurrentContext) current();
414         
415         StatusImpl status = (StatusImpl) StatusImpl.FACTORY.object();
416         status._args = status._args1;
417         status._args[0] = arg0;
418  
419         if ((ctx != null) && (ctx.doExecute(logic, status)))
420                 return; // Concurrent execution.
421
// Else current thread execution.
422
ARGUMENTS.set(status._args);
423         logic.run();
424         StatusImpl.FACTORY.recycle(status);
425     }
426
427     /**
428      * Executes the specified logic with the specified two arguments.
429      *
430      * @param logic the logic to execute concurrently when possible.
431      * @param arg0 the first argument.
432      * @param arg1 the second argument.
433      * @throws ClassCastException if the current context is not a
434      * {@link ConcurrentContext}.
435      * @see #execute(ConcurrentContext.Logic)
436      */

437     public static void execute(Logic logic, Object JavaDoc arg0, Object JavaDoc arg1) {
438         ConcurrentContext ctx = (ConcurrentContext) current();
439         
440         StatusImpl status = (StatusImpl) StatusImpl.FACTORY.object();
441         status._args = status._args2;
442         status._args[0] = arg0;
443         status._args[1] = arg1;
444  
445         if ((ctx != null) && (ctx.doExecute(logic, status)))
446                 return; // Concurrent execution.
447
// Else current thread execution.
448
ARGUMENTS.set(status._args);
449         logic.run();
450         StatusImpl.FACTORY.recycle(status);
451     }
452
453     /**
454      * Executes the specified logic with the specified three arguments.
455      *
456      * @param logic the logic to execute concurrently when possible.
457      * @param arg0 the first argument.
458      * @param arg1 the second argument.
459      * @param arg2 the third argument.
460      * @throws ClassCastException if the current context is not a
461      * {@link ConcurrentContext}.
462      * @see #execute(ConcurrentContext.Logic)
463      */

464     public static void execute(Logic logic, Object JavaDoc arg0, Object JavaDoc arg1,
465             Object JavaDoc arg2) {
466         ConcurrentContext ctx = (ConcurrentContext) current();
467         
468         StatusImpl status = (StatusImpl) StatusImpl.FACTORY.object();
469         status._args = status._args3;
470         status._args[0] = arg0;
471         status._args[1] = arg1;
472         status._args[2] = arg2;
473  
474         if ((ctx != null) && (ctx.doExecute(logic, status)))
475                 return; // Concurrent execution.
476
// Else current thread execution.
477
ARGUMENTS.set(status._args);
478         logic.run();
479         StatusImpl.FACTORY.recycle(status);
480     }
481
482     /**
483      * Executes the specified logic with the specified four arguments.
484      *
485      * @param logic the logic to execute concurrently when possible.
486      * @param arg0 the first argument.
487      * @param arg1 the second argument.
488      * @param arg2 the third argument.
489      * @param arg3 the fourth argument.
490      * @throws ClassCastException if the current context is not a
491      * {@link ConcurrentContext}.
492      * @see #execute(ConcurrentContext.Logic)
493      */

494     public static void execute(Logic logic, Object JavaDoc arg0, Object JavaDoc arg1,
495             Object JavaDoc arg2, Object JavaDoc arg3) {
496         ConcurrentContext ctx = (ConcurrentContext) current();
497         
498         StatusImpl status = (StatusImpl) StatusImpl.FACTORY.object();
499         status._args = status._args4;
500         status._args[0] = arg0;
501         status._args[1] = arg1;
502         status._args[2] = arg2;
503         status._args[3] = arg3;
504  
505         if ((ctx != null) && (ctx.doExecute(logic, status)))
506                 return; // Concurrent execution.
507
// Else current thread execution.
508
ARGUMENTS.set(status._args);
509         logic.run();
510         StatusImpl.FACTORY.recycle(status);
511     }
512
513     /**
514      * Executes the specified logic with the specified five arguments.
515      *
516      * @param logic the logic to execute concurrently when possible.
517      * @param arg0 the first argument.
518      * @param arg1 the second argument.
519      * @param arg2 the third argument.
520      * @param arg3 the fourth argument.
521      * @param arg4 the fifth argument.
522      * @throws ClassCastException if the current context is not a
523      * {@link ConcurrentContext}.
524      * @see #execute(ConcurrentContext.Logic)
525      */

526     public static void execute(Logic logic, Object JavaDoc arg0, Object JavaDoc arg1,
527             Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4) {
528         ConcurrentContext ctx = (ConcurrentContext) current();
529         
530         StatusImpl status = (StatusImpl) StatusImpl.FACTORY.object();
531         status._args = status._args5;
532         status._args[0] = arg0;
533         status._args[1] = arg1;
534         status._args[2] = arg2;
535         status._args[3] = arg3;
536         status._args[4] = arg4;
537  
538         if ((ctx != null) && (ctx.doExecute(logic, status)))
539                 return; // Concurrent execution.
540
// Else current thread execution.
541
ARGUMENTS.set(status._args);
542         logic.run();
543         StatusImpl.FACTORY.recycle(status);
544     }
545
546     /**
547      * Executes the specified logic with the specified six arguments.
548      *
549      * @param logic the logic to execute concurrently when possible.
550      * @param arg0 the first argument.
551      * @param arg1 the second argument.
552      * @param arg2 the third argument.
553      * @param arg3 the fourth argument.
554      * @param arg4 the fifth argument.
555      * @param arg5 the sixth argument.
556      * @throws ClassCastException if the current context is not a
557      * {@link ConcurrentContext}.
558      * @see #execute(ConcurrentContext.Logic)
559      */

560     public static void execute(Logic logic, Object JavaDoc arg0, Object JavaDoc arg1,
561             Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4, Object JavaDoc arg5) {
562         ConcurrentContext ctx = (ConcurrentContext) current();
563         
564         StatusImpl status = (StatusImpl) StatusImpl.FACTORY.object();
565         status._args = status._args6;
566         status._args[0] = arg0;
567         status._args[1] = arg1;
568         status._args[2] = arg2;
569         status._args[3] = arg3;
570         status._args[4] = arg4;
571         status._args[5] = arg5;
572  
573         if ((ctx != null) && (ctx.doExecute(logic, status)))
574                 return; // Concurrent execution.
575
// Else current thread execution.
576
ARGUMENTS.set(status._args);
577         logic.run();
578         StatusImpl.FACTORY.recycle(status);
579     }
580
581     // Implements Context abstract method.
582
protected void enterAction() {
583         _inheritedExecutors = getExecutors();
584         _error = null;
585         _initiatedCount = 0;
586         _completedCount = 0;
587     }
588
589     // Implements Context abstract method.
590
protected void exitAction() {
591         synchronized (this) {
592             while (_initiatedCount != _completedCount) {
593                 try {
594                     this.wait();
595                 } catch (InterruptedException JavaDoc e) {
596                     throw new ConcurrentException(e);
597                 }
598             }
599         }
600         // Propagates any concurrent error to current thread.
601
if (_error != null) {
602             if (_error instanceof RuntimeException JavaDoc)
603                 throw ((RuntimeException JavaDoc) _error);
604             if (_error instanceof Error JavaDoc)
605                 throw ((Error JavaDoc) _error);
606             throw new ConcurrentException(_error); // Wrapper.
607
}
608     }
609    
610     private boolean doExecute(Logic logic, StatusImpl status) {
611         if (_isEnabled) {
612             status._context = this;
613             ConcurrentExecutor[] executors = _inheritedExecutors;
614             for (int i = 0; i < executors.length; i++) {
615                 if (executors[i].execute(logic, status)) {
616                     _initiatedCount++;
617                     return true; // Done.
618
}
619             }
620         }
621         return false;
622     }
623     
624     /**
625      * <p> This abstract class represents some parameterized code which may be
626      * executed concurrently.</p>
627      */

628     public static abstract class Logic implements Runnable JavaDoc {
629
630         /**
631          * Returns the arguments (if any) for this logic execution.
632          *
633          * @return an array holding the arguments.
634          */

635         public Object JavaDoc[] getArguments() {
636             return (Object JavaDoc[]) ARGUMENTS.get();
637         }
638
639         /**
640          * Returns the specified arguments for this logic execution.
641          *
642          * @return an array holding the arguments.
643          */

644         public/*<T>*/Object JavaDoc/*{T}*/getArgument(int i) {
645             return (Object JavaDoc/*{T}*/) ((Object JavaDoc[]) ARGUMENTS.get())[i];
646         }
647
648         /**
649          * Executes this logic, arguments (if any) can be retrieved using
650          * the {@link #getArguments} method.
651          */

652         public abstract void run();
653
654     }
655
656     /**
657      * Returns the maximum number of concurrent thread.
658      *
659      * @return <code>(Number of Processors)</code>
660      * @see javolution.context.ConcurrentThread
661      */

662     private static Integer JavaDoc concurrency() {
663         Reflection.Method availableProcessors = Reflection
664                 .getMethod("java.lang.Runtime.availableProcessors()");
665         if (availableProcessors != null) {
666             Integer JavaDoc processors = (Integer JavaDoc) availableProcessors.invoke(Runtime
667                     .getRuntime());
668             return new Integer JavaDoc(processors.intValue());
669         } else {
670             return new Integer JavaDoc(1);
671         }
672     }
673
674     /**
675      * Returns the maximum number of concurrent thread.
676      *
677      * @return <code>(Number of Processors) - 1</code>
678      * @see javolution.context.ConcurrentThread
679      */

680     private static class StatusImpl extends RealtimeObject implements Status {
681
682         private static StatusImpl.Factory FACTORY = new Factory() {
683             protected Object JavaDoc create() {
684                 return new StatusImpl();
685             }
686             protected void cleanup(Object JavaDoc status) {
687                 ((StatusImpl)status).reset();
688             }
689
690         };
691
692         volatile Object JavaDoc[] _args;
693
694         Object JavaDoc[] _args0 = new Object JavaDoc[0];
695
696         Object JavaDoc[] _args1 = new Object JavaDoc[1];
697
698         Object JavaDoc[] _args2 = new Object JavaDoc[2];
699
700         Object JavaDoc[] _args3 = new Object JavaDoc[3];
701
702         Object JavaDoc[] _args4 = new Object JavaDoc[4];
703
704         Object JavaDoc[] _args5 = new Object JavaDoc[5];
705
706         Object JavaDoc[] _args6 = new Object JavaDoc[6];
707
708         ConcurrentContext _context;
709
710         public void started() {
711             ARGUMENTS.set(_args);
712             Context.setCurrent(_context);
713             _context.getLocalPools().activatePools();
714         }
715
716         public void completed() {
717             _context.getLocalPools().deactivatePools();
718  
719             // Must be last (as the status may be reused after).
720
synchronized (_context) {
721                 _context._completedCount++;
722                 _context.notify();
723             }
724         }
725
726         public void error(Throwable JavaDoc error) {
727             synchronized (_context) {
728                 if (_context._error == null) {
729                     _context._error = error;
730                 }
731             }
732         }
733
734         void reset() {
735             for (int i = 0; i < _args.length; i++) {
736                 _args[i] = null; //
737
}
738             _context = null;
739         }
740     }
741 }
Popular Tags