Threads in Applets

Applets are embeddable Java applications that are expected to be able to start and stop themselves on command. Applets may be asked to start and stop themselves any number of times. A Java-enabled web browser normally starts an applet when the applet is displayed and stops it when the user moves to another page or (in theory) when the user scrolls the applet out of view. To conform to the semantics of the API, we would like an applet to cease its nonessential activity when it is stopped and resume it when started again. (If you’re not familiar with applets, you may want to take a look at Chapter 20, at this point.)

In this section, we will build UpdateApplet, a simple base class for an applet that maintains a thread to automatically update its display at regular intervals. Although we’re building an applet here, the general technique is important for all threaded applications.

UpdateApplet handles the basic starting and stopping behavior for us:

//file: UpdateApplet.java
public class UpdateApplet extends java.applet.Applet  
    implements Runnable {  
     
    private Thread updateThread;  
    int updateInterval = 1000;  

    public void run( ) {  
        while ( updateThread != null ) {  
            try {    
                Thread.sleep( updateInterval );   
            }
            catch (InterruptedException e ) { 
                return;
            }  
            repaint( );  
        }  
    }  
  
    public void start( ) {  
        if ( updateThread == null ) {  
            updateThread = new Thread(this);  
            updateThread.start( );  
        }  
    }  

    public void stop( ) {  
        if ( updateThread != null ) {  
            Thread runner = updateThread;
            updateThread = null;  // flag to quit
            runner.interrupt( );   // wake up if asleep
        }  
    }  
}

UpdateApplet is a Runnable object that alternately sleeps and calls its repaint( ) method. (There’s nothing to paint, though, so running this applet is kind of boring. Later in this section, we’ll subclass it to implement a digital clock.) It has two other public methods: start() and stop( ). These are methods of the Applet class we are overriding; don’t confuse them with the similarly named methods of the Thread class. These start() and stop( ) methods are called by the Java runtime system, to tell the applet when it should and should not be running.

UpdateApplet illustrates an environmentally friendly way to deal with threads in a simple applet. UpdateApplet effectively kills its thread each time the applet is stopped and recreates it if the applet is restarted. When UpdateApplet’s start( ) method is called, we first check to make sure there is no currently executing updateThread. We then create one to begin our execution. When our applet is subsequently asked to stop, we set a flag indicating that it should stop and then make sure it is awake by invoking its interrupt() method. In our stop( ) method, we set updateThread to null, which serves three purposes: it allows the garbage collector to clean up the dead Thread object; it indicates to UpdateApplet’s start( ) method that the thread is gone, so that another one can be started when necessary; and we use it as the flag to indicate to the running thread that it is time to quit. If you feel that we have overburdened this variable, you might consider using a separate boolean variable for the flag condition.

One thing about Applets: in truth, an Applet’s start() and stop( ) methods are guaranteed to be called in sequence. As a result, we shouldn’t have to check for the existence of updateThread in start( ). (It should always be null.) However, it’s good programming practice to perform the test. If we didn’t, and for some reason stop( ) were to fail at its job, we might inadvertently start a lot of threads.

With UpdateApplet doing all of the work for us, we can now create the world’s simplest clock applet with just a few lines of code. Figure 8.3 shows our Clock. (This might be a good one to run on your Java wristwatch.)

//file: Clock.java
public class Clock extends UpdateApplet {  
    public void paint( java.awt.Graphics g ) {  
        g.drawString( new java.util.Date().toString( ), 10, 25 );
    }  
}
The Clock applet

Figure 8-3. The Clock applet

The java.util.Date().toString( ) method creates a string that contains the current time.

Our Clock applet provides a good example of a simple thread; we don’t mind throwing it away and subsequently rebuilding it if the user should happen to wander on and off of our web page a few times. But what if the task that our thread handles isn’t so simple? What if, for instance, we have to open a socket and establish a connection with another system? One solution is to use Thread’s suspend( ) and resume( ) methods, as we’ll show you in a moment.

Now if you’re concerned about being so cavalier in creating and discarding Thread objects, you might rightly ask if we couldn’t simply do a little more logic and save our thread. Perhaps we could teach the start( ) method to have the existing thread begin again., rather than having to create a new thread. It should be apparent how to go about this using the wait() and notify( ) methods after you read the next section on thread synchronization.

However, an issue with applets is that we have no control over how a user navigates web pages. For example, say a user scrolls our applet out of view, and we pause our thread. Now we have no way of ensuring that the user will bring the applet back into view before moving on to another page. And actually, the same situation would occur if the user simply moves on to another page and never comes back. That’s not a problem in this simple example, but there may be cases in which we need to do some application cleanup before we die. For this situation the Applet API gives us the destroy( ) method. destroy( ) is called by the Java runtime system when the applet is going to be removed (often from a cache). It provides a place at which we can free up any resources the applet is holding.

Get Learning Java now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.