KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > clif > scenario > util > isac > engine > behavior > BehaviorExecutionPooledThread


1 /*
2  * CLIF is a Load Injection Framework
3  * Copyright (C) 2004 France Telecom R&D
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * CLIF
20  *
21  * Contact: clif@objectweb.org
22  */

23 package org.objectweb.clif.scenario.util.isac.engine.behavior;
24
25 import java.util.Hashtable JavaDoc;
26 import java.util.Vector JavaDoc;
27
28 import org.objectweb.clif.datacollector.api.DataCollectorWrite;
29 import org.objectweb.clif.scenario.util.isac.engine.IsacScenarioEngine;
30 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.ExecutableNode;
31 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.description.ChoiceDescription;
32 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.description.IfDescription;
33 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.description.PreemptiveDescription;
34 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.description.SampleDescription;
35 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.description.TestDescription;
36 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.description.TimerDescription;
37 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.description.WhileDescription;
38 import org.objectweb.clif.scenario.util.isac.exception.IsacRuntimeException;
39 import org.objectweb.clif.scenario.util.isac.plugin.SampleAction;
40 import org.objectweb.clif.scenario.util.isac.plugin.TestAction;
41 import org.objectweb.clif.scenario.util.isac.plugin.TimerAction;
42 import org.objectweb.clif.scenario.util.isac.util.BooleanHolder;
43 import org.objectweb.clif.scenario.util.isac.util.SessionObjectHashtable;
44 import org.objectweb.clif.scenario.util.isac.util.IntHolder;
45 import org.objectweb.clif.scenario.util.isac.util.tree.Node;
46 import org.objectweb.clif.storage.api.ActionEvent;
47 import org.objectweb.util.monolog.api.BasicLevel;
48 import org.objectweb.util.monolog.api.Logger;
49
50 /**
51  * This class is a implementation of a behavior execution thread This thread is
52  * able to execute a behavior and send the reports to the right clif module
53  *
54  * @author JC Meillaud
55  * @author A Peyrard
56  */

57 public class BehaviorExecutionPooledThread extends Thread JavaDoc {
58     // logger
59
static protected Logger log = IsacScenarioEngine.logger
60             .getLogger(BehaviorExecutionPooledThread.class.getName());
61
62     // attributes
63
// locks...
64
private Object JavaDoc suspendLock;
65
66     private Object JavaDoc poolLock;
67
68     private Object JavaDoc groupExecutionLock;
69
70     private Object JavaDoc timerLock;
71
72     private Object JavaDoc activitiesLock;
73
74     private Object JavaDoc dataControlWrite_lock;
75
76     // client interface datacontrolwrite
77
private DataCollectorWrite dataControlWrite;
78
79     // boolean running states shared with others threads and the group manager
80
private volatile BooleanHolder stopped;
81
82     private volatile BooleanHolder suspended;
83
84     // Vector storing all threads of the group, shared with the group manager
85
private Vector JavaDoc behaviorsThreads;
86
87     // int storing number of waiting thread in the group, shared with the group
88
// manager and all group threads
89
private IntHolder behaviorsThreadsWaiting;
90
91     // int storing number of waiting thread in the group, shared with the group
92
// manager and all group threads
93
private IntHolder behaviorsThreadsRunningRequired;
94
95     private IntHolder behaviorsThreadAliveNumber;
96
97     // boolean to stop only this thread
98
private boolean localStopped;
99
100     // root tree node to be executed
101
private ExecutableNode executableNode;
102
103     // table containing all the sessions objects needed to execute this behavior
104
private SessionObjectHashtable sessionsObjectsTable;
105
106     // pile of tests
107
private Vector JavaDoc testsPile;
108
109     // id of this thread, numbre of the entry in the vector
110
private int threadId;
111
112     // id of the group, used in debug mode to know whose thread is printing msg
113
private int groupId;
114
115     private String JavaDoc bladeId;
116
117     /**
118      * Constructor, build a new behavior executable pooled thread
119      *
120      * @param threadId
121      * The thread id of this thread
122      * @param executableNode
123      * The executable node to be executed
124      * @param sot
125      * The sessions objects table
126      * @param sl
127      * The suspendLock used to execute suspend operation
128      * @param pl
129      * The pool lock to synchronize access on pool values
130      * @param tl
131      * The timer lock used to execute a wait time
132      * @param al
133      * The lock used to switch in sleeping mode, outside an exec
134      * @param gel The object to notify the group execution thread
135      * @param dcw
136      * The data control write client interface
137      * @param dcwl
138      * The lock for this interface
139      * @param stopped
140      * The boolean which tell if the behavior is in stopped state
141      * @param suspended
142      * The boolean which tell if the behavior is in suspended state
143      * @param bt
144      * The vector which store each thread of a group
145      * @param btw
146      * The reference on an integer which represents the number of
147      * waiting threads
148      * @param btrr
149      * The reference of an integer which represents the number of
150      * threads required for this group
151      * @param btan
152      * The number of behaviors alive in this pool
153      */

154     public BehaviorExecutionPooledThread(String JavaDoc bladeId, int threadId,
155             ExecutableNode executableNode, SessionObjectHashtable sot, Object JavaDoc sl,
156             Object JavaDoc pl, Object JavaDoc tl, Object JavaDoc al, Object JavaDoc gel,
157             DataCollectorWrite dcw, Object JavaDoc dcwl, BooleanHolder stopped,
158             BooleanHolder suspended, Vector JavaDoc bt, IntHolder btw, IntHolder btrr,
159             IntHolder btan)
160     {
161         this.bladeId = bladeId;
162         this.threadId = threadId;
163         this.executableNode = executableNode;
164         this.sessionsObjectsTable = sot;
165         this.suspendLock = sl;
166         this.poolLock = pl;
167         this.timerLock = tl;
168         this.activitiesLock = al;
169         this.groupExecutionLock = gel;
170         this.dataControlWrite = dcw;
171         this.dataControlWrite_lock = dcwl;
172         this.stopped = stopped;
173         this.suspended = suspended;
174         this.behaviorsThreads = bt;
175         this.behaviorsThreadsWaiting = btw;
176         this.behaviorsThreadsRunningRequired = btrr;
177         this.behaviorsThreadAliveNumber = btan;
178         // init the local stopped state
179
this.localStopped = false;
180         // init the test pile
181
this.testsPile = new Vector JavaDoc();
182     }
183
184     /**
185      * This method is the method which is called when we used the method start()
186      * on the thread, we will wait on the activity object then we will be notify
187      * we will execute the executable node of the behavior tree, and after that
188      * redo wait and exec 'till the stopped state will be set
189      *
190      * @see java.lang.Runnable#run()
191      */

192     public void run() {
193         // increment the number of alive threads
194
synchronized (this.groupExecutionLock) {
195             this.behaviorsThreadAliveNumber
196                     .setIntValue(this.behaviorsThreadAliveNumber.getIntValue() + 1);
197         }
198         // never stop the thread 'till the stopped state
199
while (!this.stopped.getBooleanValue()) {
200             synchronized (this.activitiesLock) {
201                 synchronized (this.poolLock) {
202                     // remove the thread from the running threads
203
this.behaviorsThreads.remove(this);
204                     // if the suspend state is on
205
if (this.suspended.getBooleanValue()) {
206                         if (this.behaviorsThreadsWaiting.getIntValue() == this.behaviorsThreads
207                                 .size()) {
208                             // notify the pool because all
209
// threads
210
// are in
211
// waiting(suspending) state
212
this.poolLock.notify();
213                         }
214                     }
215                     // if local stop has been invoked
216
if (this.localStopped) {
217                         // decrement the required thread number
218
this.behaviorsThreadsRunningRequired
219                                 .setIntValue(this.behaviorsThreadsRunningRequired
220                                         .getIntValue() - 1);
221                         if (this.behaviorsThreadsRunningRequired.getIntValue() == 0) {
222                             // notify the pool because we are the last one to
223
// start
224
this.poolLock.notify();
225                         }
226                         // unset the localStopped value
227
this.localStopped = false;
228                     }
229                 }
230
231                 log.log(BasicLevel.DEBUG, "\t\t-- BET -- WAIT WORK TO DO");
232                 // put the thread in a waiting state
233
try {
234                     this.activitiesLock.wait();
235                 } catch (InterruptedException JavaDoc ex) {
236                     // should not append, we could throw an exception too
237
log.log(BasicLevel.WARN,
238                             "The thread have beeen interrupted, so stop it");
239                     break;
240                 }
241             }
242             synchronized (this.poolLock) {
243                 // test if the stopped state have not changed
244
if (this.stopped.getBooleanValue())
245                     break;
246
247                 // add this thread to the behaviors running vector
248
this.behaviorsThreads.add(this);
249
250                 // decrement the required thread number
251
this.behaviorsThreadsRunningRequired
252                         .setIntValue(this.behaviorsThreadsRunningRequired
253                                 .getIntValue() - 1);
254                 if (this.behaviorsThreadsRunningRequired.getIntValue() == 0) {
255                     // notify the pool because we are the last one to start
256
this.poolLock.notify();
257                 }
258             }
259             // execute the behavior (run the things the thread have to run)
260
this.executeNode(this.executableNode);
261             // prepare the next execution, reset all session objects values
262
sessionsObjectsTable.reset() ;
263         } // while
264
// call close method on all session object, this method
265
// will close active connections...
266
sessionsObjectsTable.close() ;
267         // decrement the pool alive threads number
268
log.log(BasicLevel.DEBUG, "\t\t-- BET --" + "WAIT FOR DIEING");
269         synchronized (this.groupExecutionLock) {
270             this.behaviorsThreadAliveNumber
271                     .setIntValue(this.behaviorsThreadAliveNumber.getIntValue() - 1);
272             if (this.behaviorsThreadAliveNumber.getIntValue() == 0) {
273                 log.log(BasicLevel.DEBUG, "\t\t-- BET --"
274                         + "WE ARE THE LAST ONE NOTIFY THE GROUP...");
275                 // if we are the last one of this pool to stop,
276
// notify the group execution
277
this.groupExecutionLock.notify();
278             }
279         }
280         log.log(BasicLevel.WARN, "This thread DIE !!!");
281     }
282
283     /**
284      * The method which execute a node executable
285      *
286      * @param node
287      * The node to be executed
288      */

289     private void executeNode(ExecutableNode node) {
290         log.log(BasicLevel.DEBUG, "\t\t-- BET -- executeNode");
291         // test if all the test in the pile are still right //TODO test suspend or stop
292
for (int i = 0; i < this.testsPile.size(); i++) {
293             // if the test is not right stop the execution of this node
294
if (!this
295                     .executeTest((TestDescription) this.testsPile.elementAt(i)))
296                 return;
297         }
298         // init a boolean which store if we need to execute the children of
299
// the node
300
boolean executeChildren = false;
301         // execute the specific method for this kind of node
302
String JavaDoc type = node.getType();
303         // sample
304
if (type.equals(Node.SAMPLE)) {
305             executeChildren = executeSample(node);
306         }
307         // timer
308
else if (type.equals(Node.TIMER)) {
309             executeChildren = executeTimer(node);
310         }
311         // if
312
else if (type.equals(Node.IF)) {
313             executeChildren = executeIf(node);
314         }
315         // while
316
else if (type.equals(Node.WHILE)) {
317             executeChildren = executeWhile(node);
318         }
319         // preeptive
320
else if (type.equals(Node.PREEMPTIVE)) {
321             executeChildren = executePreemptive(node);
322         }
323         // nchoice
324
else if (type.equals(Node.NCHOICE)) {
325             executeChildren = executeNChoice(node);
326         }
327         // choice or then or else, just execute the children
328
else if (type.equals(Node.CHOICE) || type.equals(Node.THEN)
329                 || type.equals(Node.ELSE) || type.equals(Node.BEHAVIOR)) {
330             executeChildren = true;
331         }
332         // should never append
333
else {
334             throw new IsacRuntimeException(
335                     "This node type is UNKNOW, could not execute it : " + type);
336         }
337         // if we need to execute children
338
if (executeChildren) {
339             for (int i = 0; i < node.getChildren().size() && !this.localStopped
340                     && !this.stopped.getBooleanValue(); i++) {
341                 this.executeSuspendIfNeeded();
342                 this.executeNode((ExecutableNode) node.getChildren().elementAt(
343                         i));
344             }
345         }
346     }
347
348     /**
349      * Execute a sample node
350      *
351      * @param node
352      * The executable node to be executed
353      * @return false, because we don't need to execute the children
354      */

355     private boolean executeSample(ExecutableNode node) {
356         log.log(BasicLevel.DEBUG, "\t\t-- BET -- execute sample : ");
357         // get the sample description of the node
358
SampleDescription desc = (SampleDescription) node.getDescription();
359         // get the datas
360
Object JavaDoc sessionObject = this.sessionsObjectsTable.get(desc
361                 .getSessionObjectId());
362         Hashtable JavaDoc params = desc.getParams();
363         int nb = desc.getMethodNumber();
364         // execute the doSample method on the session object
365
ActionEvent report = ((SampleAction) sessionObject).doSample(nb,
366                 params, new ActionEvent(System.currentTimeMillis(), bladeId, null, 0,
367                         threadId, true, 0, null, ""));
368         // send the result to the clif component if not null
369
if (report != null)
370         {
371             synchronized (this.dataControlWrite_lock) {
372                 if (this.dataControlWrite != null)
373                     this.dataControlWrite.add(report);
374             }
375         }
376         // we don't need to execute the children,
377
// because this kind of node could not has children
378
return false;
379     }
380
381     /**
382      * Execute a timer node
383      *
384      * @param node
385      * The executable node to be executed
386      * @return false, because we don't need to execute the children
387      */

388     private boolean executeTimer(ExecutableNode node) {
389         log.log(BasicLevel.DEBUG, "\t\t-- BET -- execute timer : ");
390         // get the timer description of the node
391
TimerDescription desc = (TimerDescription) node.getDescription();
392         // get the datas
393
Object JavaDoc sessionObject = this.sessionsObjectsTable.get(desc
394                 .getSessionObjectId());
395         Hashtable JavaDoc params = desc.getParams();
396         int nb = desc.getMethodNumber();
397         // execute the doTimer method on the session object
398
long waitingTime = ((TimerAction) sessionObject).doTimer(nb, params);
399         // execute a waiting method during the time of the stop
400
this.executeWaitTime(waitingTime);
401         // we don't need to execute the children,
402
// because this kind of node could not has children
403
return false;
404     }
405
406     /**
407      * Method which executes an if executable node
408      *
409      * @param node
410      * The executable node to be executed
411      * @return false, because, we organize the execution of the children in this
412      * method
413      */

414     private boolean executeIf(ExecutableNode node) {
415         log.log(BasicLevel.DEBUG, "\t\t-- BET -- execute if : ");
416         // get the value of the condition
417
boolean condition = executeTest(((IfDescription) node.getDescription())
418                 .getCondition());
419         log.log(BasicLevel.DEBUG, "\t\t-- BET -- condition : " + condition);
420         // get the then child and the else child if it exists
421
ExecutableNode thenNode = null;
422         ExecutableNode elseNode = null;
423         // the size should be 1 or 2
424
for (int i = 0; i < node.getChildren().size() && !this.localStopped
425                 && !this.stopped.getBooleanValue(); i++) {
426             this.executeSuspendIfNeeded();
427             // get a child
428
ExecutableNode child = (ExecutableNode) node.getChildren()
429                     .elementAt(i);
430             if (child.getType().equals(Node.THEN))
431                 thenNode = child;
432             else if (child.getType().equals(Node.ELSE))
433                 elseNode = child;
434             else
435                 throw new IsacRuntimeException("Unexpected node type : "
436                         + child.getType());
437         }
438         // if we have been stopped don't execute the children
439
if (this.localStopped || this.stopped.getBooleanValue()) {
440             return false;
441         }
442         log.log(BasicLevel.DEBUG, "\t\t-- BET -- then node : " + thenNode);
443         // execute the right child depending on the condition
444
if (condition)
445             this.executeNode(thenNode);
446         else if (elseNode != null)
447             this.executeNode(elseNode);
448         // don't launch the children, because it's already done
449
return false;
450     }
451
452     /**
453      * Method which executes a while executable node
454      *
455      * @param node
456      * The executable node to be executed
457      * @return false, because, we organize the execution of the children in this
458      * method
459      */

460     private boolean executeWhile(ExecutableNode node) {
461         log.log(BasicLevel.DEBUG, "\t\t-- BET -- execute while : ");
462         // get the value of the condition
463
boolean condition = executeTest(((WhileDescription) node
464                 .getDescription()).getCondition());
465         // while the condition is right do it
466
while (condition && !stopped.getBooleanValue() && !localStopped) {
467             // execute all child
468
for (int i = 0; i < node.getChildren().size() && !this.localStopped
469                     && !this.stopped.getBooleanValue(); i++) {
470                 this.executeSuspendIfNeeded();
471                 this.executeNode((ExecutableNode) node.getChildren().elementAt(
472                         i));
473             }
474             // revaluate the condition
475
condition = executeTest(((WhileDescription) node.getDescription())
476                     .getCondition());
477         }
478         // don't launch the children, because it's already done
479
return false;
480     }
481
482     /**
483      * This method execute a preemptive node
484      *
485      * @param node
486      * The excutable node to execute
487      * @return false, because, we organize the execution of the children in this
488      * method
489      */

490     private boolean executePreemptive(ExecutableNode node) {
491         log.log(BasicLevel.DEBUG, "\t\t-- BET -- execute preemptive : ");
492         // put the test of this node in the tests pile
493
this.testsPile.add(((PreemptiveDescription) node.getDescription())
494                 .getCondition());
495         // execute the child all this child will evaluate the condition
496
// putted in the pile
497
for (int i = 0; i < node.getChildren().size() && !this.localStopped
498                 && !this.stopped.getBooleanValue(); i++) {
499             this.executeSuspendIfNeeded();
500             this.executeNode((ExecutableNode) node.getChildren().elementAt(i));
501         }
502         // remove the test from the pile
503
this.testsPile.remove(node.getDescription());
504         // don't launch the children, because it's already done
505
return false;
506     }
507
508     /**
509      * This method execute a nchoice node
510      *
511      * @param node
512      * The excutable node to execute
513      * @return false, because, we organize the execution of the children in this
514      * method
515      */

516     private boolean executeNChoice(ExecutableNode node) {
517         log.log(BasicLevel.DEBUG, "\t\t-- BET -- execute nchoice : ");
518         // create a table to store all the probabilities, one for each child
519
int[] probabilityRange = new int[node.getChildren().size()];
520         // init a counter to adds the propabilities
521
int totalPorbablities = 0;
522         // init this vector
523
for (int i = 0; i < node.getChildren().size(); i++) {
524             int proba = ((ChoiceDescription) ((ExecutableNode) node
525                     .getChildren().elementAt(i)).getDescription())
526                     .getProbability();
527             totalPorbablities += proba;
528             probabilityRange[i] = totalPorbablities;
529         }
530         // get a random value between 0 and totalProbabilities
531
int random = (int) (Math.random() * totalPorbablities);
532         // get the right choice
533
for (int i = 0; i < probabilityRange.length; i++) {
534             // must be true only one time...
535
if (random < probabilityRange[i]) {
536                 if (!this.localStopped && !this.stopped.getBooleanValue()) {
537                     this.executeSuspendIfNeeded();
538                     // execute this branch : i
539
this.executeNode((ExecutableNode) node.getChildren()
540                             .elementAt(i));
541                 }
542                 // don't launch the children, because it's already done
543
return false;
544             }
545         }
546         // should never append
547
throw new IsacRuntimeException(
548                 "Unable to make a choice, no branch was selected");
549     }
550
551     /**
552      * This method execute a test
553      *
554      * @param td
555      * The test description which will be executed
556      * @return The result of the test
557      */

558     private boolean executeTest(TestDescription td) {
559         log.log(BasicLevel.DEBUG, "\t\t-- BET -- execute test");
560         // get the datas
561
Object JavaDoc sessionObject = this.sessionsObjectsTable.get(td
562                 .getSessionObjectId());
563         Hashtable JavaDoc params = td.getParams();
564         int nb = td.getMethodNumber();
565         // execute the doTimer method on the session object
566
return ((TestAction) sessionObject).doTest(nb, params);
567     }
568
569     /**
570      * Method which execute a timer, if the thread switch to suspend mode,
571      * execute the suspend but redo the timer in the same state than before the
572      * suspend
573      *
574      * @param duration
575      * The duration of the timer
576      */

577     private void executeWaitTime(long duration) {
578         if (IsacScenarioEngine.DEBUG_ON && log.isLoggable(BasicLevel.DEBUG)) {
579             log.log(BasicLevel.DEBUG, "\t\t-- BET -- execute wait : "
580                     + duration);
581         }
582         // define a variable to store the elapsed_time if a suspend append
583
long ellapsedTime = 0;
584         // do this since the duration time has not been wait, and
585
// since the stop state don't append
586
while (ellapsedTime < duration && !stopped.getBooleanValue()
587                 && !localStopped) {
588             // try to do suspend
589
this.executeSuspendIfNeeded();
590             // store the starting time
591
long startTimerTime = System.currentTimeMillis();
592             // synchronize on the timer object
593
synchronized (this.timerLock) {
594                 try {
595                     this.timerLock.wait(duration - ellapsedTime);
596                 } catch (InterruptedException JavaDoc ex) {
597                     throw new IsacRuntimeException("-- BET" + threadId + ":"
598                             + groupId + " Unable to execute timer", ex);
599                 }
600             }
601             // if we reach this line, either we sleep all the duration time
602
// or the group execution stop us in order to do a stop or
603
// suspend mode
604
// calcul the time we manage to wait
605
ellapsedTime += System.currentTimeMillis() - startTimerTime;
606         }
607     }
608
609     /**
610      * This method analyse if we are in suspended state and wait during the
611      * suspended state if we are
612      */

613     private void executeSuspendIfNeeded() {
614         // synchronized (this.scenarioLock) {
615
if (this.suspended.getBooleanValue()) {
616             log
617                     .log(BasicLevel.WARN,
618                             "\t\t-- BET -- WE MANAGE TO ENTER SUSPEND");
619             synchronized (this.suspendLock) {
620                 log.log(BasicLevel.WARN,
621                         "\t\t-- BET -- WE MANAGE TO ENTER groupexec LOCK");
622                 synchronized (this.poolLock) {
623                     // increments the number of waiting threads
624
this.behaviorsThreadsWaiting
625                             .setIntValue(this.behaviorsThreadsWaiting
626                                     .getIntValue() + 1);
627                     log.log(BasicLevel.WARN, "\t\t-- BET -- threads running="
628                             + this.behaviorsThreads.size() + " waiting="
629                             + this.behaviorsThreadsWaiting.getIntValue());
630                     if (this.behaviorsThreadsWaiting.getIntValue() == this.behaviorsThreads
631                             .size()) {
632                         // notify the pool
633
log.log(BasicLevel.WARN,
634                                 "\t\t-- BET -- awake GROUPPPPPPPPP");
635                         this.poolLock.notify();
636                     }
637                 }
638                 log.log(BasicLevel.WARN, "\t\t-- BET -- do SUSPEND");
639                 try {
640                     this.suspendLock.wait();
641                 } catch (InterruptedException JavaDoc ex) {
642                     throw new IsacRuntimeException(
643                             "Unable to wait during the suspended state",ex);
644                 }
645                 synchronized (this.poolLock) {
646                     // now decrease the number of thread suspended
647
this.behaviorsThreadsWaiting
648                             .setIntValue(this.behaviorsThreadsWaiting
649                                     .getIntValue() - 1);
650                     if (this.behaviorsThreadsWaiting.getIntValue() == 0) {
651                         // notify the pool because we are the
652
// last thread entering resume mode
653
// of this group
654
this.poolLock.notify();
655                     }
656                 }
657             }
658         }
659     }
660
661     /**
662      * @param localStopped
663      * The localStopped to set.
664      */

665     public void setLocalStopped(boolean localStopped) {
666         this.localStopped = localStopped;
667     }
668 }
Popular Tags