Posted by
alois on November 22, 2005 at 1:04 AM PST
Introduction
How many times have you used a thread that depend from an other one?
Personally, a lot's of time... and each time I need to implement cascading start/stop method to make threads starting in the right order.
What about using extended Thread classes that manage dependencies automatically?
Extending the thread class (ThreadWithDependencies)
I want enabling dependence between thread to automatic starting/stopping in a cascading way.
A thread can start only if all his parents are running, I need to implement method to manage dependence and automatically start/stop childs.
First of all, methods for dependencies management:
- addChild
- removeChild
- addParent
- removeParent
Then methods for starting/stopping:
- startDependencies: Start all childs
- startWithDependencies: Start the thread and all childs
- stopDependencies: Stop all childs thread
- stopWithDependencies: Stop all childs and the thread
Using the class
Short exemple on how to use the ThreadWithDependencies class.
public class ThreadA extends ThreadWithDependencies {
public ThreadA(){
try{
addChild(new ThreadA_1());
addChild(new ThreadA_2());
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String argv[]){
Thread myThread=new ThreadA();
myThread.start();
while(myThread.isAlive()){
try{Thread.sleep(1000);}catch(Exception e){break;}
}
}
public void run(){
try{
startDependencies();
}catch(Exception e){
e.printStackTrace();
}
System.out.println("Thread A");
}
}
public class ThreadA_1 extends ThreadWithDependencies{
public void run(){
System.out.println("Thread A - 1");
}
}
public class ThreadA_2 extends ThreadWithDependencies{
public void run(){
System.out.println("Thread A - 2");
}
}
Result of execution:
Thread A
Thread A - 1
Thread A - 2
Source code
Just copy/past this source code to use it in your own software.
TODO
- Check if we not adding a child in parent and vice-versa
- Check if we not adding a running thread
- ...
public class ThreadWithDependencies extends Thread {
private Collection parents = new ArrayList();
private Collection childs = new ArrayList();
protected boolean setStopped(){
// To define in extended class
return true;
}
protected synchronized void startWithDependencies() throws ThreadWithDependenciesParentNotAliveException{
ThreadWithDependencies thread;
Iterator iterator;
// Checking if parents running
iterator=parents.iterator();
while(iterator.hasNext()){
thread=(ThreadWithDependencies)iterator.next();
if(!thread.isAlive()){throw new ThreadWithDependenciesParentNotAliveException(thread.getName());}
}
// Starting myself
super.start();
// Starting childs
startDependencies();
}
protected synchronized void startDependencies()throws ThreadWithDependenciesParentNotAliveException{
ThreadWithDependencies thread;
Iterator iterator;
// Starting childs
iterator=childs.iterator();
while(iterator.hasNext()){
thread=(ThreadWithDependencies)iterator.next();
if(!thread.isAlive()){thread.startWithDependencies();}
}
}
protected synchronized void stopWithDependencies(){
stopDependencies();
if(!setStopped()){return;}
}
protected synchronized void stopDependencies(){
ThreadWithDependencies thread;
Iterator iterator;
// Stopping childs
iterator=childs.iterator();
while(iterator.hasNext()){
thread=(ThreadWithDependencies)iterator.next();
thread.stopWithDependencies();
}
}
private boolean isDependenceModifiable(){
ThreadWithDependencies thread;
Iterator iterator;
// Checking if parents running
iterator=parents.iterator();
while(iterator.hasNext()){
thread=(ThreadWithDependencies)iterator.next();
if(thread.isAlive()){return false;}
}
return !isAlive();
}
protected void addParent(ThreadWithDependencies parent) throws ThreadWithDependenciesNotModifiableException{
if(!isDependenceModifiable()){throw new ThreadWithDependenciesNotModifiableException(getName());}
parents.add(parent);
}
protected void removeParent(ThreadWithDependencies parent) throws ThreadWithDependenciesNotModifiableException{
if(!isDependenceModifiable()){throw new ThreadWithDependenciesNotModifiableException(getName());}
parents.remove(parent);
}
protected void addChild(ThreadWithDependencies child) throws ThreadWithDependenciesNotModifiableException{
if(!isDependenceModifiable()){throw new ThreadWithDependenciesNotModifiableException(getName());}
childs.add(child);
}
protected void removeChild(ThreadWithDependencies child) throws ThreadWithDependenciesNotModifiableException{
if(!isDependenceModifiable()){throw new ThreadWithDependenciesNotModifiableException(getName());}
childs.remove(child);
}
}
class ThreadWithDependenciesNotModifiableException extends Exception{
static final long serialVersionUID=0;
public ThreadWithDependenciesNotModifiableException(){super();}
public ThreadWithDependenciesNotModifiableException(String reason){super(reason);}
}
class ThreadWithDependenciesParentNotAliveException extends Exception{
static final long serialVersionUID=0;
public ThreadWithDependenciesParentNotAliveException(){super();}
public ThreadWithDependenciesParentNotAliveException(String reason){super(reason);}
}
Java API Implementation
I didn't found any thread dependencies management in API, but I think it's a nice feature that can be really useful if implemented in Java API...