附源程序:
GreatRace.javaimport goodFrame; 
import java.awt.Graphics; 
import java.awt.GridLayout; 
import Threader; 
public class GreatRace extends java.applet.Applet implements Runnable{ 
Threader theRacers[]; 
static int racerCount = 3; 
Thread theThreads[]; 
Thread thisThread; 
static boolean inApplet=true; 
int numberofThreadsAtStart; 
public void init(){ 
//we will use this later to see if all our Threads have died 
numberofThreadsAtStart = Thread.activeCount(); //Specify the layout. We will be adding all of the racers one on top 
//of the other. setLayout(new GridLayout(racerCount,1)); //Specify the number of racers in this race, and make the arrays for the 
//Threaders and the actual threads the proper size. 
theRacers = new Threader [racerCount]; 
theThreads = new Thread[racerCount]; //Create a new Thread for each racer, and add it to the panel 
for (int x=0;x<racerCount;x++){ 
theRacers[x]=new Threader ("Racer #"+x); 
theRacers[x].resize(size().width,size().height/racerCount); 
add (theRacers[x]); 
theThreads[x]=new Thread(theRacers[x]); } 

public void start(){ 
//Start all of the racing threads 
for (int x=0;x<racerCount;x++) 
theThreads[x].start(); 
//Create a thread of our own. We will use this to monitor the state of 
//the racers and determine when we should quit all together 
thisThread= new Thread (this); 
thisThread.start(); 

public void stop(){ 
thisThread.stop(); 

public void run(){ 
//Loop around until all of the racers have finished the race. 
while(Thread.activeCount()>numberofThreadsAtStart+2){ 
try{ 
thisThread.sleep(100); 
} catch (InterruptedException e){ 
System.out.println("thisThread was interrupted"); 

} //Once the race is done, end the program 
if (inApplet){ 
stop(); 
destroy(); 

else 
System.exit(0); 

public static void main (String argv[]){ 
inApplet=false; //Check to see if the number of racers has been specified on the command line 
if (argv.length>0) 
racerCount = Integer.parseInt(argv[0]); //Create a new frame and place the race in it. 
goodFrame theFrame = new goodFrame("The Great Thread Race"); 
GreatRace theRace = new GreatRace(); 
theFrame.resize(400,200); 
theFrame.add ("Center",theRace); 
theFrame.show(); 
theRace.init(); 
theFrame.pack(); 
theRace.start(); 

}//end class GreatRaceThreader.javaimport java.awt.Graphics; 
import java.awt.Color; 
public class Threader extends java.awt.Canvas implements Runnable { 
int myPosition =0; 
String myName; 
int numberofSteps=600; 
//Constructor for a Threader. We need to know our name when we 
//create the Threader 
public Threader (String inName){ 
myName=new String (inName); 

public synchronized void paint(Graphics g){ 
//Draw a line for the 'racing line' 
g.setColor (Color.black); 
g.drawLine (0,size().height/2,size().width,size().height/2); 
//Draw the round racer; 
g.setColor (Color.yellow); 
g.fillOval((myPosition*size().width/numberofSteps),0,15,size().height); 

public void run(){ 
//loop until we have finished the race 
while (myPosition <numberofSteps){ 
//move ahead one position 
myPosition++; 
repaint(); //Put ourselves to sleep so the paint thread can get around to painting. 
try{ 
Thread.currentThread().sleep(10); 
}catch (Exception e){System.out.println("Exception on sleep");} 

System.out.println("Threader:"+myName+" has finished the race"); 

}//end class Threader