// // Very simple program demonstrating the use of threads. // // Command-line argument is P (number of threads). // // Synchronization via class (static) method. // // (This version is functionally identical to ThreadsHello2 // but is meant to be more Java-esque.) // // ---- Class containing main program -------------------------------- public class ThreadsHello3 { private int nThreads; // Constructor. public ThreadsHello3(int P) { nThreads = P; } // Method to do the intended work. public void greet() { // Create objects for threads. Hello3[] objs = new Hello3[nThreads]; for (int i = 0; i < nThreads; ++i) objs[i] = new Hello3(i); // Create threads, start them up, and wait for them to finish. ThreadManager tMgr = new ThreadManager(objs); tMgr.start(); tMgr.join(); } // Main method. public static void main(String[] args) { if (args.length < 1) { System.err.println("Usage: java ThreadsHello3 numThreads"); System.exit(1); } int P = Integer.parseInt(args[0]); ThreadsHello3 obj = new ThreadsHello3(P); obj.greet(); System.out.println("That's all, folks!"); } } // ---- Class to contain data and code for each thread --------------- class Hello3 implements Runnable { private int myID; // Constructor. public Hello3(int myID) { this.myID = myID; } // Defines behavior of thread using this object -- // invoked by "start()" on thread. public void run() { printMsg(myID); } // Prints "hello" message. // "synchronized" keyword for class method means only one // thread at a time can execute this method. private static synchronized void printMsg(int ID) { System.out.print("hello, world, "); // pointless pause, included to make the effects of // synchronization (or lack thereof) more obvious pause(1); System.out.println("from thread " + ID); } // Sleeps for n milliseconds. private static void pause(int n) { try { Thread.sleep(n); } catch (InterruptedException e) { // should never happen } } }