Download the JDK
Search the Tutorials
Hide the TOC
Trail: Deployment
Lesson: Applets
Section: Practical Considerations When Writing Applets
Subsection: Threads in Applets
Applets
Getting Started with Applets
Importing Classes and Packages for Applets
Defining an Applet Subclass
The Life Cycle of an Applet
Methods for Milestones
Methods for Drawing and Event Handling
Methods for Adding UI Components
What Applets Can and Can't Do
Taking Advantage of the Applet API
Finding and Loading Data Files
Displaying Short Status Strings
Displaying Documents in the Browser
Sending Messages to Other Applets
Playing Sounds
Defining and Using Applet Parameters
Deciding Which Parameters to Support
Writing the Code to Support Parameters
Giving Information about Parameters
Using the APPLET Tag
Practical Considerations When Writing Applets
Security Restrictions
Creating a User Interface
Creating a GUI
Displaying Diagnostics to the Standard Output and Error Streams
Getting System Properties
Threads in Applets
Threads in Applets: Examples
Working with a Server-Side Application
A Simple Network Client Applet
Using a Server to Work Around Security Restrictions
Finishing an Applet
Before You Ship that Applet
The Perfectly Finished Applet
Deploying Applets
General Deployment Considerations
Using the applet Tag
Using the object Tag
Using the embed Tag
Deploying Applets in a Mixed-Browser Environment
Solving Common Applet Problems
Questions and Exercises
Home Page > Deployment > Applets
« Previous • Trail • Next »
Threads in Applets: Examples

> This page discusses two examples of using threads in applets. The first applet, AnimatorApplet, shows how to use a thread to perform repeated tasks. The second applet this page discusses, SoundExample, shows how to use threads for one-time initialization tasks. SoundExample is featured in Playing Sounds.

> This page does not explain basic thread code. To learn about the Java implementation of threads, refer to Defining and Starting a Thread.

### Using a Thread to Perform Repeated Tasks

> An applet that performs the same task over and over again typically should have a thread with a `while` (or `do...while`) loop that performs the task. A typical example is an applet that performs timed animation, such as a movie player or a game. Animation applets need a thread that requests repaints at regular intervals. Another example is an applet that reads data supplied by a server-side application. (See Using a Server to Work Around Security Restrictions for such an example.)

> Applets typically create threads for repetitive tasks in the applet `start` method. Creating the thread there makes it easy for the applet to stop the thread when the user leaves the page. All you need to do is implement the `stop` method so that it stops the applet's thread. When the user returns to the applet's page, the `start` method is called again, and the applet can again create a thread to perform the repetitive task.

> Below is `AnimatorApplet`'s implementation of the `start` and `stop` methods.

> >     public void start() {
> >         if (frozen) {
> >             //Do nothing.  The user has requested that we
> >             //stop changing the image.
> >         } else {
> >             //Start animating!
> >             if (animatorThread == null) {
> >                 animatorThread = new Thread(this);
> >             }
> >             animatorThread.start();
> >         }
> >     }

> >     public void stop() {
> >         animatorThread = null;
> >     }

> The `this` in `new Thread(this)` indicates that the applet provides the body of the thread. It does so by implementing the `java.lang.Runnable` interface, which requires the applet to provide a `run` method that forms the body of the thread. We'll discuss `AnimatorApplet`'s `run` method more a little later.

> Notice that nowhere in the `AnimatorApplet` class is the `Thread stop` method called. This is because calling the `Thread stop` method is like clubbing the thread over the head. It's a drastic way to get the thread to stop what it's doing. Instead, you can write the thread's `run` method in such a way that the thread will gracefully exit when you tap it on the shoulder. This shoulder tap comes in the form of setting to null an instance variable of type `Thread`.

> In `AnimatorApplet`, this instance variable is called `animatorThread`. The `start` method sets it to refer to the newly created `Thread` object. When the applet needs to kill the thread, it sets `animatorThread` to null. This kills the thread not by making it be garbage collected — it can't be garbage collected while it's runnable — but because at the top of its loop, the thread checks `animatorThread`, continuing or exiting depending on the value of `animatorThread`. Here's the relevant code:

> >     public void run() {
> >         . . .
> >         while (Thread.currentThread() == animatorThread) {
> >             ...//Display a frame of animation and then sleep.
> >         }
> >     }

> If `animatorThread` refers to the same thread as the currently executing thread, the thread continues executing. If, on the other hand, `animatorThread` is null, the thread exits. If `animatorThread` refers to another thread, then a race condition has occurred: `start` has been called so soon after `stop` (or this thread has taken such a long time in its loop) that `start` has created another thread before this thread reached the top of its `while` loop. Whatever the cause of the race condition, this thread should exit.

> For more information about animation applets, see Creating the Animation Loop, a section in Creating a GUI with JFC/Swing.

### Using a Thread to Perform One-Time Initialization

> If your applet needs to perform some initialization task that can take a while, you should consider ways of performing the initialization in a thread. For example, anything that requires making a network connection should generally be done in a background thread. Fortunately, GIF, PNG, and JPEG image loading is automatically done in the background using threads that you don't need to worry about.

> Sound loading, unfortunately, is not guaranteed to be done in the background. In current implementations, the `Applet getAudioClip` methods don't return until they've loaded all the audio data. As a result, if you want to preload sounds, you might want to create one or more threads to do so.

> Using a thread to perform a one-time initialization task for an applet is a variation of the classic producer/consumer scenario. The thread that performs the task is the producer, and the applet is the consumer. Synchronization discusses how to use Java threads in a producer/consumer scenario.

> SoundExample adheres closely to the model presented in Synchronizing Threads. Like the Synchronizing Threads example, SoundExample features three classes:

> - The producer: `SoundLoader`, a `Thread` subclass.
> - The consumer: `SoundExample`, an `Applet` subclass. Unlike the Synchronizing Threads consumer example, `SoundExample` is not a `Thread`; it doesn't even implement the `Runnable` interface. However, the `SoundExample` instance methods are executed by at least two threads, depending on the application that executes the `SoundExample` applet.
> - The storage object: `SoundList`, a `Hashtable` subclass. Unlike `CubbyHole` in the Synchronizing Threads example, `SoundList` can return null values if the sound data hasn't been stored yet. This makes sense for this applet because it needs to be able to react immediately to a user request to play the sound, even if the sound hasn't been loaded yet.
> For more information on `SoundExample`, go to Playing Sounds.

« Previous • Trail • Next »
Previous page: Threads in Applets
Next page: Working with a Server-Side Application