Chapter 11

!

Threads





Java is not the first programming language to support multi-threading. It is, though, the first to provide direct language support for both threads and the graphical user interface tools (in the Abstract Windowing Toolkit) that we have used to develop all of our lablets. This combination allows us to write programs that are responsive to their users in ways that are not easily achieved using other languages. In essence, we can now write programs that are capable of responding to user interface events while they are performing some other processing.
In the case of this chapter's lablet, TickTock, we have what appears to be a simple implementation of a modern digital alarm clock. What is interesting about it from a programming standpoint is that the program actually performs like a real clock. That is to say, while it is busy displaying and updating the current time, it is still responsive to button clicks which can interrupt this processing. When alternate processing, like setting the alarm, is completed, the program returns to its regular processing without a hitch. This, of course, is all made possible by the fact that TickTock uses a thread.
In the exercises that follow we'll analyze and experiment with TickTock's use of threads, and we'll extend it to accomplish more threaded behavior.


Lab Objectives

In this lab, you will:
 o

Run and experiment with the Chapter 11 lablet, TickTock, to understand its operation.

 o

Analyze the lablet's use of threads and how they affect its performance.

 o

Extend the lablet to implement another threaded mode of behavior, a chronometer.

Exercises

  1. We start, as usual, by running our lablet. The good news is that the operation of the TickTock program is very realistic in that it operates much like a modern digital clock or watch might. The bad news is that as a result of this realism our program is every bit as confusing to use (at first glance, anyhow) as is any new digital clock. Your first job, then, is to run the program and to use it enough so that you understand how it works. We'll offer the following hint to get you going: The clock has two modes, time mode and alarm mode.

    1. Compile and run TickTock now. Notice which buttons have been enabled and which have been disabled as you run it. Then, click on whatever buttons are enabled, and see what happens. Try setting the alarm. Once you see how to do this, set the alarm for some time in the very near future (making sure that you take the AM/PM indicator into account), and return to clock mode. Keep track of what happens every time you click on something.

    2. Just as with real clocks, there are two ways to figure out how TickTock operates. One is to start playing with it, as in part (a). The other is to RTFM ("read the fabulous manual"). We have provided you with a simple user's manual in the text [pp. 491-493 ]. Read through that now, to make sure you didn't miss any of TickTock's features.

    3. Now, compare your users' manual with the portions of TickTock's code to see how your descriptions are reflected in the lablet.

  2. Let's experiment more directly with the lablet's code to see how it uses threads to accomplish its processing. You know the drill: Make each of these changes to the original version of TickTock, and record the impact of the change. Note in each case what type of error occurred (if one occurred at all) and/or what change in program behavior resulted from your modifications. Be forewarned that some of these changes produce very subtle differences in behavior. In some cases, you may have to click some buttons to detect the differences.

    1. Remove (or comment out) the phrase from the header of class Timer that reads:
      implements Runnable
      Result:


    2. Remove (or comment out) the entire header and body of Timer's start() method.
      Result:


    3. Change the body of Timer's start() method to read:
      clockThread = new Thread(this);
      clockThread.start();
      (that is, eliminate the surrounding if statement).
      Result:


    4. Change the statement in Timer's start() method that reads:
      clockThread = new Thread(this);
      to read
      clockThread = new Thread();
      Result:


    5. Remove the phrase from Timer's run() method that reads:
      while(clockThread != null)
      {
      and the next-to-last closing brace ("}") in that method.
      Result:


    6. Change the body of method updateTime() to read:
      hour = h;
      minute = m;
      second = s;
      repaint();
      (that is, eliminate the surrounding if statement).
      Result:


    7. Change the line in method run() that reads:
      Thread.sleep(250);
      to read:
      clockThread.sleep(250);
      Result:


    8. Change the line in Timer's run() method that reads:
      Thread.sleep(250);
      to read:
      Thread.sleep(1);
      Result:


    9. Remove (or comment out) the try and catch clauses in Timer's run() method surrounding the line that reads:
      Thread.sleep(250);
      Result:


    10. Remove (or comment out) the entire try and catch clauses--including the Thread.sleep statement--from Timer's run() method.
      Result:


  3. Return now to the original version of the lablet so that we can extend it to perform even more realistically. While each of the following extensions is independent of the others, their ordering reflects their relative difficulty. So, we recommend that you do them in the order presented.

    1. Write incrementAlarmMinute() so that it doesn't use an if statement.

    2. When the original lablet is in "alarm" mode, it displays the time in the same format it uses when in "clock" mode--that is, in "hour:minute:second" format. Normally, when setting an alarm, one isn't too concerned about the seconds. Fix the program so that when TickTock is in alarm mode, it only displays the hours and minutes, and not the seconds.

    3. Add a chronometer to our clock that can be started, and continues to display the elapsed time, even when in clock or alarm modes, until it is explicitly stopped (in other words, add a stopwatch feature to the applet). There are many ways to accomplish this, and we leave it to you to decide how you want to handle the problem. Any approach that we can think of entails some re-design of TickTock, since it presently only recognizes two modes of operation, and doesn't provide an easy way for getting, say, from alarm mode to chronometer mode.


Postlab Exercises

  1. As we discussed in Section 11.1, there are several ways of threading the execution of a program. One way--the one we used in the lablet--is to have a run() method in a separate class, and have that class either extend Thread or implement the Runnable interface. A different way is to have the applet itself implement the Runnable interface and have its own instance of a Thread and its own run() method, as we did in version 3 of the bouncing ball applet [pp. 470-471 ].
    Rewrite TickTock so that the applet has its own thread, and comment on whether you think the resulting code would be easier or harder for a programmer to read and modify.

  2. You may not be aware that there is a thriving civilization on Jupiter, happily breathing methane and enduring weather that makes a terrestrial hurricane seem like a mild zephyr. Purely by coincidence, the jovial Jovians have divided their day into 24 segments, just as we do. However, the Jovian day is considerably shorter than ours--in fact, one Earth day is equivalent to approximately 2.4386 Jovian days, so their "hours" (our translation--the Jovian word is unpronouncable by us) are 1 / 2.4386 as long as ours. Rewrite TickTock so that it keeps correct Jovian time.

  3. Threads can be used to make Sortmeister even more revealing about comparative sorting algorithms. Rewrite Sortmeister so that two sort algorithms can be applied to the same data and we can compare their performance side-by-side. That is, have your new program create two "sorting displays," each executing a different algorithm on the same original data.

Last updated: December 3, 1998
Rick Decker
Department of Computer Science
Hamilton College
Clinton, NY 13323