
A Stitch in TimeThis week we will learn to use threads in our programs.
A thread can be defined as a single locus of execution of a program. However, that definition sounds a bit abstract until you get accustomed to using threads in your programs. Let's consider a hypothetical animation as an example. Suppose you had a hare and turtle running around on the screen. Either one could start and stop independently if they each had their own thread. The two actions are essentially independent of each other. If you want, you can make threads interact, but for the most part, they each run on their own.
When you create animations with a programming language, you should use threads to conserve machine cycles, if for no other reason. The thread can be stopped by the browser when you hide the page on which the animation resides, and this is nice, because it would probably be wasteful to keep it executing while you cannot see it.
To use a thread to control your animation, you can write an init, a stop, a start, and a run method for your applet. The start and stop methods can be used to start and stop the thread, and can be very similar to the way they were written for the applet we are about to look at. init is normally used to initialize things such as instance variables or the setup of the screen. The core of the program is what you put in the run method. In order to use these methods and have them properly recognized by the browser, you need to put the phrase implements Runnable after extends Applet at the beginning of your code for your applet. Runnable is the name of an interface in the JDK. Essentially, the implements phrase lets the browser or other unit that uses the applet know that it should expect certain methods to be found there, and that it should feel free to call them.
For an example of an actual, but not very useful, program that uses a thread, take a look at the BottlesOfBeer applet below. It keeps cycling as long as the mouse pointer is not in the applet. If you move the pointer inside, the applet stops. You don't need to click. Move the mouse back out again, and the applet continues, essentially where it left off. However, this is not strictly true. It actually goes to the beginning of the run method, with the bottle counter still at the same value it had when the applet was stopped. Try stopping the program at different points in its cycle (after one line is showing, or after two, three, or all four). Look at the source code for its run method, posted below, and try to figure out how it works. Note that when you stop or start the applet with the mouse, some information appears in the status bar at the bottom of your browser. You can also look at the applet's complete source code.
Question: Is there any way you can make the number of bottles of beer go negative? Try to make that happen.
Notice what happens if you cover part of the applet with another window, then expose it again. Try it in different parts of the cycle. Do you understand why it happens? Look at the repaint method, and consider when it is called.
The Bottles of Beer Applet
public void run() {
while (true) {
phase=1; /**** phase 1 ****/
try {Thread.sleep(sleepTime);}
catch(InterruptedException e) {}
if (counter != 1)
theString=counter+" bottles of beer on the wall";
else
theString="1 bottle of beer on the wall";
y=40;
repaint(); /**** clear screen, then: x bottles of beer on the wall ****/
phase=2; /**** phase 2 ****/
try {Thread.sleep(sleepTime);}
catch(InterruptedException e) {}
if (counter != 1)
theString=counter+" bottles of beer";
else
theString="1 bottle of beer";
y=80;
repaint(); /**** x bottles of beer ****/
phase=3; /**** phase 3 ****/
try {Thread.sleep(sleepTime);}
catch(InterruptedException e) {}
if (counter != 1)
theString="if one of the bottles should happen to fall";
else
theString="and if that bottle should happen to fall ...";
y=120;
repaint(); /**** if one of the bottles should happen to fall ****/
phase=4; /**** phase 4 ****/
counter--; /**** counter-- ****/
try {Thread.sleep(sleepTime);}
catch(InterruptedException e) {}
if (counter != 1)
theString=counter+" bottles of beer on the wall";
else
theString="1 bottle of beer on the wall";
y=160;
repaint(); /**** x bottles of beer on the wall ****/
if (counter <= 0)
counter = howmany;
}
}
Some Afterthoughts
By the way, it is probably a good policy to have an animation start when the mouse enters the applet, and stop when it leaves. The BottlesOfBeer applet does just the opposite. But, what can you expect after the programmer has had ten bottles of beer? Let that be a reminder that you should not program or drive a car after you've had too much to drink.
In truth, I was not under the influence of beer when I wrote this program. I was just remembering what we used to sing on the bus during elementary school field trips.
Go drink some Java!
Last modified April 14, 1997