TaskScheduler


This class monitors multiple threads, starting each thread in  a prescribed order.

/** 
* Modify that order by rewriting the
* method runTasks() to indicate the desired order of thread
* execution. This scheduler does not require threads to sleep()
* or do any polling of the monitor. The monitor starts threads
* according to the algorithm you code in runTasks(). 
*/
public class TaskScheduler {
private int nbrOfTasks;
private boolean allDone = false;
private boolean[] isDone;
private Task[] tasks;

// The constructor instantiates the number of threads
// passed to it, sets up an array to track which
// threads have completed, then calls runTask().
public TaskScheduler(int nbrOfTasks) {
this.nbrOfTasks = nbrOfTasks;

// set up the array of threads to execute 
tasks = new Task[ nbrOfTasks ];
for( int i=0; i<nbrOfTasks; i++ ) {
tasks[i] = new Task( i, this );
} /* endfor */

// set an array of booleans, indicating which
// threads have completed.
isDone = new boolean[nbrOfTasks];
for( int i=0; i<nbrOfTasks; i++ )
isDone[i] = false;

// call the synchronized method that runs one
// or more threads in a programmed sequence
runTasks();
}

// Re-write this method to handle the number of
// threads and sequence of execution you want.
// The code here is for 5 threads, 0 thru 4, in
// which 0 must finish before 1 and 2 start,
// 1 must finish before 3 starts, and
// 2 & 3 must finish before 4 starts.
public synchronized void runTasks() {
while (!allDone) {
startTask(0);

if( isDone[0] )
startTask(1);

if( isDone[0] )
startTask(2);

if( isDone[1] )
startTask(3);

if( isDone[2] && isDone[3] )
startTask(4);

// wait() till notify()ed by setTasksDone()
try {
wait();
} catch ( InterruptedException e ) {
}
} /* endwhile */
for( int i=0; i<nbrOfTasks; i++ ) 
tasks[i] = null;
isDone = null;
tasks = null;
}

// Called when a thread has permission to run. Don't
// run if already done or if currently in progress.
private void startTask( int dex ) {
if( ! isDone[dex] && ! tasks[dex].isAlive() )
tasks[dex].start();
}

public synchronized void setTaskDone( int dex ) {
isDone[dex] = true;

// Count the number to tasks completed, and set
// all_done to true if all tasks have completed.
int temp = 0;
for( int i=0; i<nbrOfTasks; i++ )
if( isDone[i] ) temp++;
if( temp == nbrOfTasks ) 
allDone = true;

// Now wake up runTasks(), which was wait()ing.
notify(); 
}

// Start up the test routine: 5 threads, using the
// rules encoded in runTasks().
public static void main(String[] args) {
TaskScheduler sch = new TaskScheduler(5);
}
}

// This class encapsulates the common attributes of threads
// that will be managed by our TaskScheduler class.
class Task extends Thread {
protected int taskNumber;
protected TaskScheduler sch;
public Task( int taskNumber, TaskScheduler sch) { 
super();
this.taskNumber = taskNumber;
this.sch = sch;
setPriority(Thread.NORM_PRIORITY - 1);
}

public void run() {
// Here you use a switch() statement to run whatever code
// is assigned to each instance of Task (each thread).

// Log in, sleep some random time from 0 to 3 secs, log out
System.out.println("Task " + (taskNumber) + " started."); 
try {
this.sleep( (long)(Math.random()*3000 ) ); 
} catch ( InterruptedException ignored ) { } 
System.out.println("\t\t\tTask " + (taskNumber) + " completed."); 

// before exiting, call the monitor's method to track completed threads.
sch.setTaskDone( taskNumber );
}
}

Note : After you have studied the above code :
» Copy it onto your hard drive in Notepad or MS Word or any text editor. Save the file as "TaskScheduler.java".
» Open a new text document, mention the applet parameters within the html parameters and save this file as "TaskScheduler.html".
» Compile the .java file (from DOS  prompt if you are not using a visual editor like VJ++, etc.) to check for errors and to obtain the .class file.
» Run at DOS prompt, using the command : java TaskScheduler




Added on June 11, 2007 Comment
}