rockcairn logoRockCairn.com rockcairn logo
/**
* RunnableThreads.java
*
* @author Aaron Penner
* @version 1.0
*/

// Java class imports
import java.lang.*;
import java.io.*;

/**
* This class runs a process using many threads
*/
class RunThreads {
// variables shared with inner thread class
private int cooperative_product = 0;
private int curr_num_threads = 100;
private static final int num_threads = 100;

// innner thread class extends Thread
class RunExample extends Object implements Runnable {

private int _num = 0;

public RunExample(int num) {
_num = num;
}

/**
* All thread classes use this to contain the
* thread processing information.
*/
public void run() {

// do some parallel task
addToCooperativeProduct(_num);

// take some time to represent some meaningful task
try {
this.wait(200);
} catch (InterruptedException e) {
System.out.print("sleep interrupted\n");
}

// debug
System.out.println("In Thread num: " + _num );

//at exit decrement the thread count.
decThreads();

}
}

/**
* This provides synchronized access to the cooperative_product
* variable, which allow only one process at a time to add to
* the parallel process total.
*
* The synchronized key word provides a locking mechanism that
* blocks threads trying to access this method.
*/
public synchronized void addToCooperativeProduct(int num){
cooperative_product += num;
}

/**
* This provides synchronized access to cooperative_product variable.
* Anything done in this method block is basically in a critical secion.
*/
public synchronized int getCooperativeProduct(){
return cooperative_product;
}

/**
* This provides synchronized access to curr_num_threads variable,
* and then we decrement the variable.
*/
public synchronized void decThreads(){
curr_num_threads--;
}

/**
* This provides synchronized access to the curr_num_threads
* that exist.
*/
public synchronized int getThreads(){
return curr_num_threads;
}

// run the threads
public void runThreads() {
int a = num_threads;

// create a way to reference the treads
Thread p[] = new Thread[num_threads];

for (int x = 0; x < num_threads; x++){
RunExample runEx = new RunExample(x);
p[x] = new Thread(runEx);
p[x].start();
}

// wait for each thread to finish in order
System.out.print("Wait for worker threads to complete\n");
for (int i=0; i < num_threads; ++i) {

// wait for each one to end any rejoin the main thread
try {
p[i].join();
} catch (InterruptedException e) {
System.out.print("Join interrupted\n");
}

// short circut to completion if the thread count is zero
if ((a = getThreads()) == 0) {
break;
} else {
System.out.println(i+" :Thread count is:" + a);
}
}

System.out.println("Final value in cooperative_producting is: " + getCooperativeProduct());

}
}

/**
* RunnableThreads is the class to run the application.
* This class runs threads by making a class which is Runnable.
*/
public class RunnableThreads {

// run the threads
public static void main(String[] args) {
RunThreads rt = new RunThreads();
rt.runThreads();

}
}