BBS水木清华站∶精华区

发信人: abcd12 (Forgiven Not Forgoten), 信区: Java        
标  题: java thread programming 
发信站: BBS 水木清华站 (Sun Aug 13 22:46:07 2000) 
 
This chapter shows just how simple it is to get a new thread up and running 
 in a tiny Java application. The first thread is the "main" thread that is a 
lways spawned by the Java Virtual Machine (JavaVM) and starts an application 
. This main thread then spawns the second thread. Each of these threads will 
 print its messages to the console to demonstrate that they both appear to b 
e running simultaneously. 
The steps to spawn a new thread in this chapter's example are 
Extend the java.lang.Thread class. 
Override the run() method in this subclass of Thread. 
Create an instance of this new class. 
Invoke the start() method on the instance. 
Extending the java.lang.Thread Class 
An instance of the java.lang.Thread class is associated with each thread run 
ning in the JavaVM. These Thread objects serve as the interface for interact 
ing with the underlying operating system thread. Through the methods in this 
 class, threads can be started, stopped, interrupted, named, prioritized, an 
d queried regarding their current state. 
---------------------------------------------------------------------------- 
---- 
NOTE: There are two ways to create a new class that can have a thread runnin 
g within it. One way is to extend the Thread class. The other is to extend a 
ny class and implement the Runnable interface. For the sake of illustration, 
 extending Thread is the simplest approach and is initially used in this boo 
k. Implementing the Runnable interface tends to work much better in the real 
 world; this technique is introduced in Chapter 4, "Implementing Runnable Ve 
rsus Extending Thread." 
---------------------------------------------------------------------------- 
---- 
In this example, the first step towards spawning a new thread is to extend t 
he java.lang.Thread class: 
public class TwoThread extends Thread { 
    // ... 

The subclass TwoThread IS-A Thread and consequently inherited the protected  
and public members from its superclass. TwoThread can be started, stopped, i 
nterrupted, named, prioritized, and queried regarding its current state, in  
addition to all the other behaviors added to the extended class. Figure 2.1  
shows the class diagram for TwoThread. 
FIGURE 2.1 The class diagram for TwoThread. 
---------------------------------------------------------------------------- 
---- 
NOTE: In this book, the notation used for class relationships is closely bas 
ed on the Unified Modeling Language (UML). Figure 2.2 shows an example of re 
lationships. 
---------------------------------------------------------------------------- 
---- 
FIGURE 2.2 A sample class diagram showing generic relationships. 
---------------------------------------------------------------------------- 
---- 
NOTE: Different terms are used in this book to describe interclass relations 
hips. All the following phrases are true about the relationships depicted in 
 Figure 2.2: 
ClassA is the superclass of ClassB. 
ClassB is a subclass of ClassA. 
ClassB extends ClassA. 
ClassB IS-A ClassA. 
ClassB implements InterfaceF. 
ClassB IS-A InterfaceF. 
ClassB is the superclass of ClassC and ClassD. 
ClassC is a subclass of both ClassB and ClassA. 
ClassC IS-A ClassB, ClassC IS-A ClassA, and ClassC IS-A InterfaceF. 
ClassE contains (at least one reference to) ClassB. 
ClassE HAS-A ClassB reference within it. 
---------------------------------------------------------------------------- 
---- 
Overriding the run() Method 
After extending Thread, the next step is to override the run() method becaus 
e the run() method of Thread does nothing: 
public void run() { } 
When a new thread is started, the entry point into the program is the run()  
method. The first statement in run() will be the first statement executed by 
 the new thread. Every statement that the thread will execute is included in 
 the run() method or is in other methods invoked directly or indirectly by r 
un(). The new thread is considered to be alive from just before run() is cal 
led until just after run() returns, at which time the thread dies. After a t 
hread has died, it cannot be restarted. 
In this chapter's example, run() is overridden with code to loop for 10 iter 
ations and print the message New thread each time through: 
public void run() { 
    for ( int i = 0; i < 10; i++ ) { 
        System.out.println("New thread"); 
    } 

After the for loop completes, the thread returns from the run() method and q 
uietly dies. 
Spawning a New Thread 
New threads are spawned from threads that are already running. First, a new  
Thread instance must be constructed. In this example, a new TwoThread object 
 will work just fine because TwoThread IS-A Thread: 
TwoThread tt = new TwoThread(); 
The next step is to kick off the execution of the thread by invoking the sta 
rt() method on the TwoThread object ( start() is inherited from Thread): 
tt.start(); 
A call to start() returns right away and does not wait for the other thread  
to begin execution. In start(), the parent thread asynchronously signals thr 
ough the JavaVM that the other thread should be started as soon as it's conv 
enient for the thread scheduler. At some unpredictable time in the very near 
 future, the other thread will come alive and invoke the run() method of the 
 Thread object (or in this case, the overridden run() method implemented in  
TwoThread). Meanwhile, the original thread is free to continue executing the 
 statements that follow the start() call. 
The two threads run concurrently and independently. On a multi-processor mac 
hine, these two threads may actually be running at the very same instant , e 
ach on its own processor. This true simultaneity would also have to be suppo 
rted in the port of the JavaVM for that platform in order to exploit multipl 
e processors. 
A more likely case is that only a single processor is present. The JavaVM an 
d the operating system work together to schedule each thread for short, inte 
rleaved bursts of processor usage. Each thread takes a turn running while th 
e other threads are frozen, waiting for their next turn on the processor. Th 
is context switching among threads generally occurs very quickly and gives t 
he illusion of truly simultaneous execution. 
---------------------------------------------------------------------------- 
---- 
CAUTION: A newly created thread may start executing (enter the run() method) 
 at any time after start() is invoked. This means that the original thread m 
ight be swapped out before any statement that follows start() is executed. 
If the original thread is executing this code: 
stmt1(); 
tt.start(); 
stmt2(); 
and the new thread has a run() method such as this: 
public void run() { 
    stmtA(); 
    stmtB(); 

the order of actual statement execution in the processor might be stmt1(), t 
t.start(), stmt2(), stmtA(), and stmtB(). Alternatively, it might be stmt1() 
, tt.start(), stmtA(), stmtB(), and stmt2(). Perhaps, it might be one of the 
 other permutations! 
Important to note is that although the order in which each thread will execu 
te its own statements is known and straightforward, the order in which the s 
tatements will actually be run on the processor is indeterminate, and no par 
ticular order should be counted on for program correctness. 
---------------------------------------------------------------------------- 
---- 
Putting It All Together 
Combining the preceding code and adding a second 10-iteration loop for the m 
ain thread to run produces the complete code for TwoThread.java, shown in Li 
sting 2.1. 
Listing 2.1 TwoThread.java--The Complete Code for the TwoThread Example 
 1: public class TwoThread extends Thread { 
 2:     public void run() { 
 3:         for ( int i = 0; i < 10; i++ ) { 
 4:             System.out.println("New thread"); 
 5:         } 
 6:     } 
 7: 
 8:     public static void main(String[] args) { 
 9:         TwoThread tt = new TwoThread(); 
10:         tt.start(); 
11: 
12:         for ( int i = 0; i < 10; i++ ) { 
13:             System.out.println("Main thread"); 
14:         } 
15:     } 
16: } 
First, note that the new class TwoThread directly extends Thread, so it IS-A 
 Thread and takes on all the capabilities of its superclass. 
Application execution begins with the main thread, which is spawned by the J 
avaVM for all applications at startup, entering the main method (line 8). It 
 proceeds to create a new TwoThread instance (line 9). Next, it spawns a new 
 thread of execution by invoking the start() method (line 10). This new thre 
ad will begin its execution by invoking the run() method (line 2) of TwoThre 
ad. 
At this point, two threads are ready to run, and the thread scheduler runs e 
ach for short periods, alternating between them. If this switching back and  
forth is fast enough, they appear to be running simultaneously. 
After the main thread spawns the new thread, the main thread proceeds into i 
ts loop (lines 12-14) and prints Main thread to the console 10 times. When i 
t is done with the loop, it falls through and returns from main(). The main  
thread dies when it returns from main(). 
At approximately the same time, the new thread enters the run() method (line 
 2), proceeds into its loop (lines 3-5), and prints New thread to the consol 
e 10 times. When it is done with the loop, it falls through and returns from 
 run(). The new thread dies when it returns from run(). 
When both threads have completed their work and died, the JavaVM shuts down  
and the application is done. 
Listing 2.2 shows possible output from running this application (your output 
 might differ). During this run of the application, the messages from the tw 
o threads happened to be perfectly interleaved, starting with the message fr 
om the main thread. There is no guarantee that this output would be the same 
 if the application was run again. Thread scheduling is nondeterministic and 
 depends on many factors, including what else is currently running in the op 
erating system. The thread scheduler makes what seem to be random decisions  
about how long each thread should be allowed to run between context switches 
. The only thing that can be counted on from running this application is tha 
t each message will print exactly 10 times, regardless of the order of the m 
essages. 
Listing 2.2 Possible Output from a Run of TwoThread.java 
Main thread 
New thread 
Main thread 
New thread 
Main thread 
New thread 
Main thread 
New thread 
Main thread 
New thread 
Main thread 
New thread 
Main thread 
New thread 
Main thread 
New thread 
Main thread 
New thread 
Main thread 
New thread 
Summary 
This chapter explores how to create a new thread by performing these tasks: 
Subclassing Thread 
Overriding the run() method of Thread to specify the statements to be execut 
ed by the new thread 
Creating a new instance of this subclass of Thread 
Spawning a new thread by invoking start() on this instance 
That's all there is to getting a second thread up and running in Java! The f 
ollowing chapters explore the complexities of threads and the coordination o 
f the intercommunication that usually must occur among them. 
 
-- 
 
   WE DON'T KNOW WHO WE ARE UNTIL WE SEE WHAT WE DO! 
 
 
※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.204.9.81] 

BBS水木清华站∶精华区