Java Q&A
by Mike Criscolo


Example 1.

MyThread thdHandle = new MyThread("This is my Thread");
thdHandle.start();


Listing One
import java.util.*;
/* QueueObject - general class that implements a queue mechanism using a Java 
 * Vector. Also implements signaling in GetQueueItem and SetQueueItem methods
 * Author:  Mike Criscolo
 */
public class QueueObject {
    protected Vector    queue;
    protected int       itemcount;
    protected String    queueName;
    public QueueObject(String name) {
        queue = new Vector();
        queueName = name;
        itemcount = 0;
    }
    // Get an item from the vector.  Wait if no items available
    public synchronized Object GetQueueItem() {
        Object   item = null;
        // If no items available, drop into wait() call
        if (itemcount == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
               System.out.println(queueName + ": Hey! Somebody woke me up!");
            }
        }
        // Get first item from vector, remove it and decrement item count.
        item = (Object)queue.firstElement();
        queue.removeElement(item);
        itemcount--;
        // Send it back
        return item;
    }
    // Place an item onto vector. Signal threads that an item is available.
    public synchronized void AddQueueItem(Object o) {
        System.out.println(queueName + ": Adding item to queue...");
        itemcount++;
        queue.addElement(o);
        notify();
    }
    // Handy place to put a separate notify call - used during shutdown.
    public synchronized void BumpQueue() {
        notify();
    }
}

Listing Two
/* RequestObject - class used to send requests between threads.
 * Author:  Mike Criscolo
 */
public class RequestObject {
    String  beginText;
    int     iSecs;
    String  responseText;

    public RequestObject() {
        beginText = "";
        responseText = "";
        iSecs = 0;
    }
    public RequestObject(String bt, int time) {
        beginText = bt;
        responseText = "";
        iSecs = time;
    }
    public void SetResponseText(String rt) {
        responseText = rt;
    }
    // Return the delay time (in seconds)
    public int GetDelayTime() {
        return iSecs;
    }
    public void Dump() {
        System.out.println("Begin: "+beginText+"  Response:" + responseText);
    }
}

Listing Three
/* Implement a Distributed queue solution for processing requests
 * with multiple threads
 * Author: Mike Criscolo
 */
public class PrimaryThread extends Thread {

    private int totThreads;
    public PrimaryThread() {
        super("PrimaryThread");
        // We'll do 2 threads
        totThreads = 2;
    }
    public void run() {
        int i;
        InspectorThread  threadArray[];
        RequestObject   reqOb;
        RequestObject   rspOb;
        int curThread = 0;
        // Create the response queue
        QueueObject rspQ = new QueueObject("Response Queue");
        threadArray = new InspectorThread[totThreads];
        // Crank the threads
        System.out.println("Cranking threads...");
        for (i = 0; i < totThreads; i++) {
            threadArray[i] = 
               new InspectorThread("User Thread " + (i + 1), (i + 1), rspQ);
            threadArray[i].start();
        }
        // Give the threads a chance to crank
        try {
            sleep(2000);
        } catch (InterruptedException e) {
            System.out.println("Bumped off the sleep() call!");
        }
        // Create some RequestObjects and hand them to the 
        // InspectorThread objects...
        for (i = 0; i < 5; i++) {
            reqOb = new RequestObject("This is item " + (i + 1), 2);
            threadArray[curThread].submitRequest(reqOb);
            curThread++;
            if (curThread == totThreads) {
                curThread = 0;
            }
        }
        // Now loop, checking the response queue for all responses
        while (i > 0) {
            rspOb = (RequestObject)rspQ.GetQueueItem();
            rspOb.Dump();
            i--;
        }
        // Kill all threads
        for (i=0; i<totThreads; i++) {
            threadArray[i].shutdown();
        }
    }
    public static void main(String argv[]) {
        PrimaryThread  pt;
        pt = new PrimaryThread();
        pt.start();
    }
}

Listing Four
import java.util.*;
/* InspectorThread - class that encapsulates the processing for
 * a thread that inspects request items.
 * Author:  Mike Criscolo
 */
public class InspectorThread extends Thread {
    protected int            threadId;
    protected boolean        running;
    protected QueueObject    requestQ;
    protected QueueObject    responseQ;

    public InspectorThread(String name, int id, QueueObject response) {

        // Call the superclass
        super(name);
        // Store the thread id and response QueueObject
        threadId = id;
        responseQ = response;
        // Create the request QueueObject for the thread to use
        requestQ = new QueueObject("Thread " + threadId + " Queue");
        running = false;
    }
    // Set the running boolean to false and bump the main loop off the wait.
    public void shutdown() {
        running = false;
        requestQ.BumpQueue();
    }
    // Main loop of the thread.
    public void run() {
        RequestObject thing;
        // Set running to true
        running = true;
        // While the thread is supposed to be running...
        while (running) {
         try {
          System.out.println("Thread "+threadId+": waiting for items...");
                // Call the QueueObject's method to get a request
                thing = (RequestObject)requestQ.GetQueueItem();
                try {
                    // Sleep for time (convert to milliseconds)
                    sleep(thing.GetDelayTime()*1000);
                } catch (InterruptedException intExp) {
                    // No problem - try again
                }
                // Put some text in the request to show we handled it
                thing.SetResponseText("Inspected by #" + threadId);
                // Send it back
                responseQ.AddQueueItem(thing);
            } catch (NoSuchElementException e) {
                // Oh well, try again
            }
        }
        System.out.println("Thread " + threadId + " exiting!");
    }
    // Add a RequestObject to the thread's queue
    public void submitRequest(Object request) {
        requestQ.AddQueueItem(request);
    }
}

Listing Five
/* Implement a Centralized queue solution for processing requests with 
 * multiple threads, with 1 long query and 4 short ones, to illustrate 
 * increased throughput
 * Author:  Mike Criscolo
 */
public class PrimaryThread extends Thread {
    private int totThreads;
    public PrimaryThread() {
        super("PrimaryThread");
        // We'll do 2 threads
        totThreads = 2;
    }
    public void run() {
        int i;

        InspectorThread  threadArray[];
        RequestObject   reqOb;
        RequestObject   rspOb;
        // Create the request and response queues
        QueueObject reqQ = new QueueObject("Request Queue");
        QueueObject rspQ = new QueueObject("Response Queue");
        threadArray = new InspectorThread[totThreads];
        // Crank the threads
        System.out.println("Cranking threads...");
        for (i = 0; i < totThreads; i++) {
            threadArray[i] = new InspectorThread("User Thread " + 
                   (i + 1), (i + 1), reqQ, rspQ);
            threadArray[i].start();
        }
        // Give the threads a chance to crank
        try {
            sleep(2000);
        } catch (InterruptedException e) {
            System.out.println("Bumped off the sleep() call!");
        }
        // Create some RequestObjects and jam them into the request queue
        for (i = 0; i < 5; i++) {
            // Last parm on next line puts a long request in first,
            // followed by short requests
            reqOb = new RequestObject("This is item "+(i+1),((i==0)?10:2));
            reqQ.AddQueueItem(reqOb);
        }
        // Now loop, checking the response queue for all responses
        while (i > 0) {
            rspOb = (RequestObject)rspQ.GetQueueItem();
            rspOb.Dump();
            i--;
        }
        // Kill all threads
        for (i=0; i<totThreads; i++) {
            threadArray[i].shutdown();
        }
    }
    public static void main(String argv[]) {
        PrimaryThread  pt;
        pt = new PrimaryThread();
        pt.start();
    }
}


5


