Multiprocessing

How can you use threads for background processing?


(Submitted by Vivek Pabby)
This is the thread that will do your "background" processing (or any task for that matter). This thread will be spawned by your main program/applet (also included here).
//
// This class implements the Runnable interface - one way to implement threads
//

class myBackgroundSlave implements Runnable
{

// The constructor - if you need it - will be executed when you instantiate this class
	public myBackgroundSlave()
	{
		// do stuff...
	}

// The run method is executed when the thread is started by your main routine - shown below
	public void run() {

		// Write code here to 
		// do whatever u want...it will be done in a separate thread
		// It will be like a background task.
		
	}	
}


//
// The main routine... that will instantiate the thread class and start it
// 
// The following class could be an applet - u can spawn a thread to do some background task from
// the applet on the click of a button or something

public class theMaster extends Applet
{

// Just in case you want this class to also execute standalone (as an application)
// u can include the main() method. It would not hurt if the class is run as an
// applet

	public static void main (String args[])	{
		new serverSocket().init();
	}

// The init method for the class. 
	public void init() {
		// do whatever......
	}

//
// The slaveDriver method will spawn the thread class above. This method can be
// invoked when the user clicks a button or something. The code that calls this method is
// not shown in this example but you can call it from wherever is required.
//

	public void slaveDriver() 
	{
// instantiate the class that will do the background processing
		myBackgroundSlave slave1 = new myBackgroundSlave();

// Create a new thread and start it. The run() method in the myBackgroundSlave will
// be started by the start() method.

		new Thread(slave1).start();
		}
	}
}

How can you efficiently synchronize two threads, if one thread depends on the other for data or tasks, but the processing time of at least one thread is indeterminate? (Hint: is a synchronized queue the answer?)


(Submitted by Steve M. Green)
Here is some code I found in the Java Programmers Guide. Two asynchronous threads ( Producer and Consumer ) are synchronised using the CubbyHole object which has several synchronized methods get() and put().

For an extreeme example of how this can be used with LOTS of threads, have a look at http://www.csiro.au:8000/steve/stuff/life/JavaLife.html. This imlements John Conway's Game of Life where every cell is running in it's own thread. The java code is in the same directory if you want to have a look. There are three classes, JavaLife.java, Cell.java and Sync.java.

This isn't the worlds most efficeint Life program, I did it as an exercise to learn how many threads could be synchronized.

If you want some more information you can email me at Steve.Green@its.csiro.au.

class Producer extends Thread {
        private CubbyHole cubbyhole;
        private int number;

        public Producer(CubbyHole c, int number) {
                cubbyhole = c;
                this.number = number;
        }

        public void run() {
                for (int i=0; i<10; i++) {
                        cubbyhole.put(i);
                        System.out.println("Producer #" + this.number + " put: "
                                 + i);
                        try {
                                sleep((int)(Math.random()*1000));
                        } catch (InterruptedException e) {}
                }
        }
}

class Consumer extends Thread {
        private CubbyHole cubbyhole;
        private int number;

        public Consumer(CubbyHole c, int number) {
                cubbyhole = c;
                this.number = number;
        }

        public void run() {
                int value = 0;
                for (int i=0; i<10; i++) {
                        value = cubbyhole.get();
                        System.out.println("Consumer #" + this.number + " got: "
                              + value);
                }
        }
}

class CubbyHole {
        private int seq;
        private boolean available=false;

        public synchronized int get() {
                while ( available == false ) {
                        try {
                                wait();
                        } catch (InterruptedException e) {}
                }
                available = false;
                return seq;
        }

        public synchronized void put(int value) {
                seq = value;
                available = true;
                notify();
        }
}

class ProducerConsumerTest {
        public static void main(String args[]) {
                CubbyHole c = new CubbyHole();
                Producer p1 = new Producer(c,1);
                Consumer c1 = new Consumer(c,1);

                p1.start();
                c1.start();
        }
}

Can one thread interfere with another?



How can I keep track of thread execution time?



How do I set up a PipedInputStream and PipedOutputStream to an external process?



How can I get threads to communicate with each other?

"I would like some notifcation to the main thread, that the slave has done something so that the main thread can do something else."


(Submitted by Vivek Pabby)
     // *****************************************
     // This code is not "refined". Some exceptions have not been
     // caught and there are a few hardcoded variables. This is just to test
     // some concepts about thread interaction.
     // *****************************************
     // Some ideas for the code have been borrowed from the javaworld site.
     // Rinaldo DiGiorgio was the author who exposed me to the inter thread
     // communication area. Please check out that work on the www.javaworld.com 
     // site if you are interested.
     // *****************************************
     
     import java.io.*;
     import java.awt.*;
     
     public class chumThreads extends java.applet.Applet implements 
     Runnable {
     
        Button                  stop = new Button("Stop");
        String                  smallTalk[] = 
                                {
                                "I will bring you up my son",
                                "Son!!",
                                "Forget it son, you are NOT getting my JAVA",
                                };
        Thread                  ParentT = null, newT = null;
        TextArea                ParentArea = null, ChildArea = null;
        PipedOutputStream       PipeOut;
        PipedInputStream        PipeIn;
        int                     sleepInterval = 5000;
     //
     // The constructor 
     //
        public chumThreads () {
                
                Font PanelFont = new Font("Dialog", Font.BOLD, 15);
                Font PanelFont3 = new Font("TimesNewRoman", Font.BOLD, 12);
                Font ParentFont = new Font("Dialog", Font.ITALIC, 15);
                Font ChildFont  = new Font("Dialog", Font.ITALIC, 15);
                ParentArea= new TextArea(8,60);
                ChildArea = new TextArea(8,60);
                
                ParentArea.setEditable(false);
                ParentArea.setBackground(Color.cyan);
                ParentArea.setFont(ParentFont);
     
                ChildArea.setEditable(false);
                ChildArea.setBackground(Color.cyan);
                ChildArea.setFont(ChildFont);
     
                setLayout(new BorderLayout());
                Panel p1 = new Panel();
                Panel p2 = new Panel();
                Panel p3 = new Panel();
                p1.setLayout(new FlowLayout());
                add("South", p1);
                p3.setLayout(new FlowLayout());
                add("North", p3);
                p2.setLayout(new FlowLayout());
                add("Center", p2);
                p1.setFont(PanelFont);
                p2.setFont(PanelFont);
                p3.setFont(PanelFont3);
                p3.add(stop);
                p1.add(new Label("This guy is ready to adopt (or is he!) [Thread - 2]"));
                p2.add(new Label("This is an orphan child!! [Thread - 1]"));
                p1.add(ParentArea);
                p2.add(ChildArea);
        }
     
        public void init() {
     //
     // Create input and output pipes and connect them (let them be useful!!!)
     //
                PipeOut = new PipedOutputStream();
                PipeIn = new PipedInputStream();
                try {
                        PipeOut.connect(PipeIn);
                } catch ( IOException e ) {
                        showStatus("Error connecting pipes in parent");
                        return;
                }
     
     //
     // Create a new thread and pass the two connected pipes to the new thread
     // The new thread and the parent thread can then share the same pipes and 
     // communicate via them
     //
                newT = new  newThread(PipeIn, PipeOut, ChildArea);
                newT.start();
        }
     
     //
     // The run() method gets invoked when this parent thread is started. The thread
     // is blocked waiting for input from the pipe. The thread proceeds further only when the 
     // new thread has written stuff to the other end of the pipe. The read() methods in
     // the PipeInputStream and PipeOutputStream class are SYNCHRONIZED - i.e. they will
     // block till input/output takes place
     //
             public void run() {
                int     dialog = 0;
     
                     while ( ParentT != null){
                        try {
                                dialog = PipeIn.read();
                        } catch ( IOException e ) {
                                showStatus("Error reading pipe in parent");
                                return;
                        } 
     //
     // Smalltalk between the parent and the new thread takes place with each
     // one using the pipe.
     //
                        ParentArea.appendText(smallTalk[dialog] + new String("\n"));     
                }
             }
             public void start() {
                ParentArea.setText("");
                ChildArea.setText("");
                     if (ParentT == null)
                     {
                             ParentT = new Thread(this);
                             ParentT.start();
                     }
             }
     
     //
     // Shut down the threads and close the pipes
     //
        public void stop() {
                ParentT = null;
                newT.stop();
                try {
                        PipeIn.close();
                        PipeOut.close();
                } catch ( IOException e ) {
                        showStatus("Error closing pipes in parent");
                        return;
                }
        }
     
        public boolean action(Event evt, Object arg) 
        {
                if ("Stop".equals(arg)) {
                        this.stop();
                        stop.setLabel("Start");
                }
                if ("Start".equals(arg))        {
                        this.init();
                        this.start();
                        stop.setLabel("Stop");
                }
                return true;
        }
     
     //
     // This method is placed here to enable this applet to run as an application also.
     //
        public static void main(String args[]) {
                Frame f1 = new Frame("Standalone Chummy Threads");
                chumThreads s1 = new chumThreads();
                s1.init();
                s1.start();
                f1.add("North", s1);
                f1.resize(600, 500);
                f1.show();      
        }
     }
     
     
     class newThread extends Thread {
     
        String                  smallTalk[] = 
                                {
                                "I am an orphan. Please adopt me", 
                                "Dad!!",
                                "Dad!, I love you man!!"
                                };
        TextArea          AreaC = null;
        int               dialog = 0;
        int               sleepInterval = 2000;
        PipedOutputStream PipeOutC;
        PipedInputStream  PipeInC;
                        
        public newThread(PipedInputStream PipeIn, PipedOutputStream 
				     PipeOut, TextArea ChildArea) {
                this.PipeOutC   = PipeOut;
                this.PipeInC    = PipeIn;
                this.AreaC      = ChildArea;
                try {
                        PipeOutC.connect(PipeInC);      
                } catch ( IOException e ) {
                        return;
                }
        }
        public void run() {
                try {
                        while ( true ){
                                
     Thread.currentThread().sleep(sleepInterval); 
                                AreaC.appendText(smallTalk[dialog] + new String("\n"));     
                                
     Thread.currentThread().sleep(sleepInterval); 
                                PipeOutC.write(dialog);
                                dialog++;
                                if (dialog > 2) dialog = 0;
                        }
                } catch ( IOException e ) {
                        return;
                } catch ( InterruptedException e ) {
                        return;
                }
        }
     }
Click to see this example run
(Submitted by Cliff Berg)
One way is to post an event to a Component controlled by the master thread. For example:
// Post a data-arrival event to the applet
Event evt1 = new Event(master, Event.ACTION_EVENT, "HI THERE MASTER!");
master.postEvent(evt1);
Notice that this requires that the slave thread has been given a handle to the "master" - probably as a parameter in the slave's constructor:
public SlaveThread(MasterThread m)
{
	// Call the superclass constructor (for Thread)
	super();

	// The slave stores reference to the master:
	master = m;
}

How do I wake up a suspended thread? Can I wake a sleeping thread?


(Submitted by Doug Erickson)
There is no way wake a Thread which has had it's sleep() method called. It will wake on it's own and continue execution when the specified time has elapsed. If you want to be able to "wake" a Thread at some future, but as yet unspecified time, use the suspend() and resume() methods.

How do I spawn an external program in Java, pass parameters to it, and return to your Java program?


(Submitted by Cliff Berg)
Here is a little example that starts Microsoft Wordpad (with document "mydoc.doc" as a parameter), and then waits for Wordpad to exit:
Runtime rt = Runtime.getRuntime();
System.out.println(rt);

Process pr = null;
try pr = rt.exec(
	"C:\\Program Files\\Accessories\\WORDPAD.EXE C:\\mydoc.doc");
catch (java.io.IOException ex1)
{
	System.out.println("IO Exception when calling exec");
	System.exit(1);
}
System.out.println(pr);
try pr.waitFor();
catch (InterruptedException ex2)
{
	System.out.println("Interrupted exception when calling waitFor");
}

How do I get two Java Applets to load at the same time?



How do I asynchronously send information or requests to a server program, and at the same time listen for responses, without getting deadlocked?