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(); } } }
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(); } }
"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 Cliff Berg)// ***************************************** // 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
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; }
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.
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"); }