A thread is a single sequential flow of control within a program. It is born, it runs, and then it dies. A thread has its own execution stack and program counter. In fact, the CPU runs one thread at a time. Chip manufacturers have gotten clever by packing memory around the CPU so that several threads have a place to wait in memory, but the CPU runs only one thread at a time. The CPU has some smarts about prioritizing threads. The specifics of how thread priorities affect scheduling are platform dependent. The Java specification just states that threads must have priorities, but it does not dictate what the scheduler should do about priorities. In a non-preemptive model, the scheduler gives higher priority threads more of a chance to run, but not necessarily get CPU time immediately. The CPU processes threads in pieces, not the entire thread at once. This piecemeal approach allows the CPU to switch between threads governed by the scheduler. That way, multithreading can occur. Java has strong multithreading capabilities. Multithreading was an early consideration when the designers at Sun started work on Java. Many languages also have this capability, but Java's application programming interface (API) for threads is simple to use and works as advertised.
Take a look at a code sample of an application that isn't thread safe, but should be. Listing 10.1 is an application that illustrates a simple problem: one part of the program being accessed simultaneously by too many other parts . Listing 10.1 An Application Using Multithreadingpublic class MultiThread1 { public static void main( String [] args ) { System.out.println( "Main Start" ); //determine number of new threads int numberOfThreads = 10; for(int i = 0; i < numberOfThreads; i++) { // create a new thread new NewThread( "Thread number " + i ).start(); } System.out.println( "Main Done" ); } } // a new thread class class NewThread extends Thread { // give thread a name public NewThread( String threadName ) { super( threadName ); System.out.println( "created " + threadName ); } // override the run method in Thread public void run() { // try to make thread sleep try { // create sleep duration in milliseconds = 0-10 seconds int milliseconds = ( int ) ( Math.random() * (10000 + 1)); int seconds = ( int ) milliseconds / 1000; String status = "NewThread name = " + getName() + "; napping for " + seconds + " seconds."; System.out.println( status ); Thread.sleep( milliseconds ); // tell system thread is awake status = getName() + " is getting up from napping."; System.out.println( status ); // Oops, interrupted } catch ( InterruptedException ex ) { ex.printStackTrace(); } } } /* results vary between runs: Main Start created Thread number 0 created Thread number 1 created Thread number 2 NewThread name = Thread number 0; napping for 3 seconds. NewThread name = Thread number 1; napping for 5 seconds. created Thread number 3 created Thread number 4 created Thread number 5 created Thread number 6 created Thread number 7 created Thread number 8 NewThread name = Thread number 2; napping for 8 seconds. NewThread name = Thread number 3; napping for 4 seconds. NewThread name = Thread number 4; napping for 3 seconds. NewThread name = Thread number 5; napping for 8 seconds. NewThread name = Thread number 6; napping for 5 seconds. NewThread name = Thread number 7; napping for 1 seconds. created Thread number 9 Main Done NewThread name = Thread number 8; napping for 0 seconds. NewThread name = Thread number 9; napping for 1 seconds. Thread number 8 is getting up from napping. Thread number 7 is getting up from napping. Thread number 9 is getting up from napping. Thread number 4 is getting up from napping. Thread number 0 is getting up from napping. Thread number 3 is getting up from napping. Thread number 1 is getting up from napping. Thread number 6 is getting up from napping. Thread number 5 is getting up from napping. Thread number 2 is getting up from napping. */ There are two classes in the program shown in Listing 10.1. NewThread is a simple class that represents a single thread. It puts itself to sleep for a random amount of time and then wakes again. The MultiThread1 class plays the master role, spawning several instances of the NewThread object. As you can see from the printout commented at the end of the listing, the threads do indeed start and stop out of order because of their different sleep lengths. Theoretically, MultiThread1 could spawn several different instances of NewThread so that 10 of the threads are alive simultaneously. That would mean 10 threads are active at the same time. With Java, you can handle this multithreaded situation easily. Perhaps the program could be adjusted somewhat so that MultiThread has more control over the NewThread instances. Listing 10.2 is a better example of one object having more control over the threads it spawns. Listing 10.2 One Object Spawning Sleeping Threadspublic class MultiThread2 { public static void main( String [] args ) { //determine number of new threads int numberOfThreads = 10; if (args.length == 1) { numberOfThreads = Integer.parseInt(args[0]); } System.out.println( "Main Start" ); for(int i = 0; i < numberOfThreads; i++) { // create sleep duration in milliseconds = 0-10 seconds int milliseconds = ( int ) ( Math.random() * (10000 + 1)); // create a new thread new NewThread( "Thread number " + i, milliseconds ).start(); } System.out.println( "Main Done" ); } } // a new thread class class NewThread extends Thread { int milliseconds = 10000; // give thread a name public NewThread( String threadName, int milliseconds ) { super( threadName ); this.milliseconds = milliseconds; System.out.println( "created " + threadName ); } // override the run method in Thread public void run() { // try to make thread take a nap try { int napLength = ( int ) milliseconds / 1000; String status = "NewThread name = " + getName() + "; napping for " + napLength + " seconds."; System.out.println( status ); Thread.sleep( milliseconds ); // tell system thread is awake status = getName() + " is getting up from napping."; System.out.println( status ); // Oops, interrupted } catch ( InterruptedException ex ) { ex.printStackTrace(); } } } //results look like that of Listing 10.1 Listing 10.2 demonstrates how easy it is to control a thread from another object. In fact, in this code 11 threads were running. There is a thread for the MultiThread object and one thread for each NewThread object. In the following section, you see another way to control a thread. |