> ### Section 7.5
> Threads, Synchronization, and Animation

> MUST AN APPLET BE COMPLETELY DEPENDENT on events sent from outside to get anything done? Can't an applet do something on its own initiative and on its own schedule? Something more like a traditional program that just executes a sequence of instructions from beginning to end?

> The answer is yes. The applet can create a thread. A thread represents a thread of control, which independently executes a sequence of instructions from beginning to end. Several threads can exist and run at the same time. An applet -- or, indeed, any Java program -- can create one or more threads and start them running. Each of the threads acts as a little program. The separate threads run independently but they can communicate with each other by sharing variables.

> One common use of threads is to do animation. A thread runs continuously while an applet is displayed. Several times a second, the thread changes the applet's display. If the changes are frequent enough, and the changes small enough, the viewer will perceive continuous motion.

> Programming with threads is called parallel programming because several threads can run in parallel. Parallel programming can get tricky when several threads are all using a shared resource. An example of a shared resource is the screen. If several threads try to draw to the screen at the same time, it's possible for the contents of the screen to become corrupted. Instance variables can also be shared resources. In order to avoid problems with shared resources, access to shared resources must be synchronized in some way. Java defines a fairly natural and easy way of doing such synchronization. I will discuss it below.

> Note that on most computers, you can't literally have two threads running "at the same time," since there is only one processor, which can only do one thing at a time. Only computers with more than one processor can literally do more than one thing at a time. However, this does not solve the synchronization problem on single-processor computers! A single-processor computer simulates multiprocessing by switching rapidly from thread to thread. Without proper synchronization, a thread can be interrupted at any time to let another thread run, and this can cause problems. Suppose, for example that a thread reads the value of an important variable just before it is interrupted. After the thread resumes, it makes a decision based on the value it just read. The problem is that, without proper synchronization, some other thread might have butted in and changed the value of the variable in the meantime! The decision that the thread makes is based on a value that is no longer necessarily valid. Synchronization can be used to make sure this doesn't happen.

> Even if an applet creates only one thread, there will still be two threads running in parallel, since there is always a user interface thread that monitors user actions and feeds events to the applet. What happens if the thread is trying to draw something at the same time that the user changes the size of the applet? What if one thread is drawing to an off-screen image at the same time another thread is copying that image to the screen? These are synchronization problems. So, even in the simple case of an apple that creates a single thread, synchronization can be an issue.

> In Java, a thread is just an object of type `Thread`. The class `Thread` is defined in the standard package `java.lang`. A thread object must have a subroutine to execute. That subroutine is always named `run()`, but there are two different places where the `run()` method might be located, depending on how the thread is programmed.

> The `Thread` class itself defines a `run()` method, which doesn't do anything. One way to make a useful thread is to define a subclass of `Thread` and override the `run()` method in your subclass to make it do something useful.

> A second way to program a thread -- and the only one I will use for the time being -- is to create a class that implements the interface called `Runnable`. This interface defines one method, "`public void run()`". (To implement this interface means to declare that the class "`implements Runnable`" and to define the method "`public void run()`" in the class.) A thread can be constructed from an object of type `Runnable`. When such a thread is run, it executes the `run()` method from the `Runnable` object. I'll give an example of all this in just a moment. The advantage of defining a thread in this way is that the `run()` method has access to all the instance variables of the object, so that the thread will be able to read and change the values of those variables. (A disadvantage is that throwing a `run()` method into a class can completely muddle the clear division of responsibilities that should be the hallmark of object-oriented programming. The `run()` method is logically part of the `Thread` object, but it is physically part of the `Runnable` object. Keep this in mind: It's best to think of the `run()` method as a separate entity.)

> Suppose that `runnableObject` is an object that implements `Runnable`. And suppose that `runner` is a variable of type `Thread`. Then the statement

> `runner = new Thread(runnableObject);`

> creates a thread that can execute the `run()` method of `runnableObject`. However, the thread does not automatically start running. To get it to run, you have to call its `start()` method:

> `runner.start();`

> The thread will then begin executing the `run()` method. At the same time, the rest of your program continues to execute. The thread continues until it reaches the end of the `run()` method. At that point it "dies" and cannot be restarted or reused. If you want to execute the same `run()` method again, you have to create a new thread to do it. You can check whether a thread is still alive by calling its `isAlive()` method, which returns a `boolean` value:

> `if (runner.isAlive()) . . .`

> (Note: it is possible to kill a thread before it finishes normally by calling its `stop()` method. However, use of this method is discouraged since it is error-prone, and I will avoid it entirely.)

> As we work through a few examples in the rest of this section, I'll be introducing several important new ideas. One of the ideas has to do with managing the state of an applet. The state of an applet consists of its instance variables. The state determines how the applet will respond when its methods are called. Managing the state means determining how and when the state should change. In many cases, it also means making the state of the applet apparent to the user, so the user isn't surprised or frustrated by the applet's behavior. One way to make the state of the applet apparent is to disable a button whenever clicking on that button would make no sense. Recall that a button, `bttn`, can be disabled with the command "`bttn.setEnabled(false);`", and it can be enabled with "`bttn.setEnabled(true);`".

> Let's look at the first example. When you click on the button in the following applet, a thread is created that blinks the color of the message from red to green and back again several times. Note that the button is disabled while the message is blinking:

> Sorry, but your browser
> doesn't support Java.

> The source code for this applet begins with the lines:

>           public class BlinkingHelloWorld1 extends Applet
>                                    implements ActionListener, Runnable {

>              ColoredHelloWorldCanvas canvas; // Canvas that displays the message

>              Button blinkBttn;  // The "Blink at Me" button.

>              Thread blinker;  // A thread that cycles the message colors.

> In this example, the applet class itself implements `Runnable`. (There is nothing special about applets in this regard. Any class can implement `Runnable`. It might be useful, for example, to have a `Runnable` canvas.) Later in the source code, the thread will be created with the command "`blinker = new Thread(this);`", where `this` refers to the applet object itself. This means that the thread we create will execute whatever `run()` method is defined in the `BlinkingHelloWorld1` class. Let's think about what we want this thread to do. (This is just like designing a small program.) We want the thread to blink the color of the message. We'll also give the thread the responsibility of disabling and enabling the button, since that way we can be sure that the button will be disabled just as long as the message is blinking. A pseudocode version of the run method would be:

>                 disable the blinkBttn
>                 set the text color to green
>                 pause for a while
>                 set the text color to red
>                 pause for a while
>                 set the text color to green
>                 pause for a while
>                 set the text color to red
>                 pause for a while
>                 set the text color to green
>                 pause for a while
>                 set the text color to red
>                 enable the blinkBttn

> The pauses are necessary since otherwise the blinking would go by much too fast to see. Unfortunately, for technical reasons, getting a thread to pause requires a `try...catch` statement, which will not be covered until Chapter 9. For the time being, I will just give you a subroutine that can be called by a thread to insert a pause in its execution:

>                 void delay(int milliseconds) {
>                       // Pause for the specified number of milliseconds,
>                       // where 1000 milliseconds equal one second.
>                    try {
>                       Thread.sleep(milliseconds);
>                    }
>                    catch (InterruptedException e) {
>                    }
>                 }

> Using this subroutine and a `setTextColor()` routine from the `ColoredHelloWorldCanvas` class, the applet's `run()` method becomes:

>                 public void run() {
>                    blinkBttn.setEnabled(false);
>                    canvas.setTextColor(Color.green);
>                    delay(300);
>                    canvas.setTextColor(Color.red);
>                    delay(300);
>                    canvas.setTextColor(Color.green);
>                    delay(300);
>                    canvas.setTextColor(Color.red);
>                    delay(300);
>                    canvas.setTextColor(Color.green);
>                    delay(300);
>                    canvas.setTextColor(Color.red);
>                    blinkBttn.setEnabled(true);
>                 }

> The `blinker` thread, which executes this run method, has to be created and started when the user clicks the "Blink at Me!" button. This is done in the applet's `actionPerformed()` method, which is called when the user clicks the button:

>                 public void actionPerformed(ActionEvent evt) {
>                    if ( blinker == null || (blinker.isAlive() == false) ) {
>                       blinker = new Thread(this);
>                       blinker.start();
>                    }
>                 }

> This routine creates and starts a thread. That thread executes the above `run()` method, which blinks the text several times. When the run method ends, the thread dies.

> I only want one of these threads to be running at a time. To be sure of this, before creating the new thread, I test whether another thread already exists and is running. Since the button is disabled while a thread is running, this test might seem unnecessary. However, it's usually better to test a condition rather than just assume it's true. And in this case, it's just possible that the user might manage to click the button a second time before the first thread gets started.

> The complete source code for this example can be found in the file BlinkingHelloWorld1.java.

> In the previous example, the thread that was created ran for only a short time, until it had run through all the instructions in its `run()` method. In many cases, though, we want a thread to run over an extended period. Often a thread that is created by an applet should run as long as the applet itself exists. Before working with such threads, though, you need to know more about an applet's life cycle.

> An applet, just like any other object, has a "life cycle." It is created, it exists for a time, and it is destroyed. The `Applet` class defines an `init()` method, which is called just after the applet is created. There are other methods in the `Applet` class which are called at other points in an applet's life cycle. A programmer can provide definitions of these methods if there are tasks that the programmer would like to have executed at those points in the applet's life cycle.

> Just before an applet object is destroyed, the method "`public void destroy()`" is called to give the applet a chance to clean up before it ceases to exist. Because of Java's automatic garbage collection, a lot of cleanup is done automatically. There are a few cases, however, where `destroy()` might be useful. In particular, if the applet has created any threads, those threads should almost certainly be stopped before the applet is destroyed. The `destroy()` method is a natural place to do this. As another example, it is possible for an applet to create a separate window on the screen. The applet's destroy method could close such a window so it doesn't hang around after the applet no longer exists.

> An applet also has methods "`public void start()`" and "`public void stop()`". These play similar roles to `init()` and `destroy()`. However, while `init()` and `destroy()` are each called exactly once during the life cycle of an applet, `start()` and `stop()` can be called many times. The `start()` method is definitely called by the system at least once when the applet object is first created, just after the `init()` method is called. The `stop()` method will definitely be called at least once, before the applet is destroyed. In addition to these calls, the system can choose to stop the applet by calling its `stop()` method at any time and then later restart it by calling its `start()` method again. For example, a Web browser will typically stop an applet if the user leaves the page on which the applet is displayed, and will restart it if the user returns to that page. An applet that has been stopped will not receive any other events until it has been restarted.

> It is not always clear what initialization should be done in `init()` and what should be done in `start()`. Things that only need to be done once should ordinarily be done in `init()`. If the applet creates a separate thread to carry out some task, it is reasonable to start that thread in the `start()` method and stop it in the `stop()` method. If the applet uses a large amount of some computer resource such as memory, it might be reasonable for it to allocate that resource in its `start()` method and release it in its `stop()` method, so that the applet will not be hogging resources when it isn't even running. On the other hand, sometimes this is impossible because the applet needs to retain the resource for its entire lifetime.

> The next example creates a thread that runs until the user clicks on a button, or until the applet itself is stopped:

> Sorry, but your browser
> doesn't support Java.

> When you click on the "Blink!" button, the message starts cycling between two colors. The name of the "Blink!" button changes to "Stop!". Clicking on the "Stop!" button will stop the blinking. (The command that changes the name of the button, `blinkBttn`, to "Stop!" is `blinkBttn.setLabel("Stop!")`. This is another case of changing the appearance of the applet when it changes state in order to help the user understand what is going on.) The other two buttons can be used at any time to set the colors that are used for the blinking message. Recall that the blinking is handled by one thread while the button events are handled by a separate user interface thread, so in this example you really do get to see two threads operating in parallel.

> The `run()` method for this example has a `while` loop that makes it blink the text over and over. The interesting question is how to get the loop to end and the thread to stop running when the user clicks the "Stop!" button. The answer is to use a shared instance variable for communication between the thread and the applet. The thread tests the value of the variable and keeps running as long as the variable has a certain value. When the user clicks on the "Stop!" button, the applet changes the value of the variable. The thread sees this change and responds by exiting from its `run()` method and dieing.

> I tend to use a variable named `status` for this type of communication. It's a good idea, for the sake of readability, to use named constants as the possible values of `status`. For this example, the status information that I need is whether the thread should continue or should end. I use constants named `GO` and `TERMINATE` to represent these two possibilities. The thread continues running as long as the value of `status` is `GO`. It ends when the value of `status` changes to `TERMINATE`. To implement this, the applet includes the following instance variables:

>        private final static int GO = 0,           // For use as values of status.
>                                 TERMINATE = 1;

>        private volatile int status; // This is used for communication between
>                                     // the applet and the thread.  The value is
>                                     // set by the applet to tell the thread what
>                                     // to do.  When the applet wants the thread
>                                     // to terminate, it sets the value of status
>                                     // to TERMINATE.

> (The word `volatile` is a new modifier that has to do with communication between threads. It should be used on a variable whose value is set by one thread and read by another. The somewhat technical reason is this: If a variable is not declared to be `volatile`, then on some computers, when one thread changes the value of the variable, other threads might not immediately see the new value. This is another type of synchronization problem. Later in this section, I'll mention "synchronized" methods and statements. Variables that are accessed only in synchronized methods and statements don't have to be declared `volatile`.)

> The idea is for the thread to run just so long as the value of `status` is `GO`. The thread's `run()` method tests the value of `status` in a `while` loop, which continues only so long as `status == GO`. Note that the value of `status` must be set equal to `GO` before the thread is started, since otherwise the `run()` method would finish immediately. When the user clicks on the "Blink!" button, the following commands are executed to start the thread:

>                 runner = new Thread(this);
>                 status = GO;
>                 runner.start();

> In addition to blinking the text, the thread is also responsible for changing the label on the button. Here is the entire `run()` method for the thread:

>                 public void run() {
>                    blinkBttn.setLabel("Stop!");
>                    while (status == GO) {
>                       waitDelay(300);
>                       changeColor();
>                    }
>                    blinkBttn.setLabel("Blink!");
>                 }

> Here, the `waitDelay()` method imposes a delay of 300 milliseconds, while `changeColor()` changes the color of the displayed message. Both these methods are defined elsewhere in the applet.

> The thread is started and stopped in the `actionPerformed()` method, in response to the user clicking on the Blink/Stop button. When the user clicks "Stop!", the value of `status` is set to `TERMINATE`. The thread sees this value and stops. But we have to be careful. What if the user never clicks on "Stop!"? We should be careful not to leave the thread running after the applet is destroyed. An applet that creates threads that might otherwise run forever should make sure to terminate them, either in its `stop()` method or in its `destroy()` method. In this example, I use the `stop()` method to stop the thread by setting `status` to `TERMINATE`. The `stop()` method will be called by the system if you close the window that displays this page or follow a link to another page (or, in Netscape, if you just resize the page). So, if you start the message blinking, go to another page, and then return to this one, the blinking should be stopped.

> In the second blinking hello world applet, there are two reasons why the color of the message might change: because the `runner` thread changes it or because the user clicks on the "Red/Green" button or the "Black/Blue" button. These two reasons are handled by two different threads. The variables that record the current color are resources that are shared by two threads. When a thread is accessing a shared resource, it usually needs exclusive access to that resource, so that no other thread can butt in and access the resource at the same time. In Java, exclusive access is implemented using synchronized methods and synchronized statements. A method is declared to be synchronized by adding the `synchronized` modifier to its definition. Here, for example, is the method that is called by the `runner` thread to change the color of the message:

>            synchronized void changeColor() {
>                   // Change from first to second color or vice versa.
>                if (showingFirstColor) {
>                      // Change to showing second color.
>                   showingFirstColor = false;
>                   if (useRedAndGreen)
>                      canvas.setTextColor(Color.green);
>                   else
>                      canvas.setTextColor(Color.blue);
>                }
>                else {
>                      // Change to showing first color.
>                   showingFirstColor = true;
>                   if (useRedAndGreen)
>                      canvas.setTextColor(Color.red);
>                   else
>                      canvas.setTextColor(Color.black);
>                }
>            }  // end changeColor()

> The other method that can change the color of the text is the `actionPerformed()` method, which is called by the user interface thread when the user clicks on one of the buttons. Like the `changeColor()` method, the `actionPerformed()` method is declared to be `synchronized`. This means that all the code that does color changes is contained inside synchronized methods. Therefore, only one of the color-change processes can be running at any given time, and there is no possibility of their interfering with each other.

> Here, briefly, is how such synchronization is implemented in Java: Every object in Java has an associated lock. The lock can be "held" by a thread, but only one thread can hold the lock at a given time. The rule is that in order to execute a synchronized method in an object, a thread must obtain that object's lock. If the lock is already held by another thread, then the second thread must wait until the first thread releases the lock. If all access to a shared resource takes place inside methods that are synchronized on the same object, then each thread that accesses the resource has exclusive access.

> When a resource is only used in part of a method, it's not necessary to make the entire method synchronized. A single statement can be synchronized. The synchronized statement takes the form

>                synchronized( object ) {
>                   statements
>                }

> (The synchronized statement, for some unknown reason, requires the braces { and } even if they contain just a single statement.) To execute the statements, a thread must first obtain the lock belonging to the specified object. Often, you will say "`synchronized(this)`" to synchronize on the same object that contains the method. However, it is also possible to synchronize on another object's lock.

> What could go wrong in the sample applet if the methods were not synchronized? For example: When the blinker thread executes, the statement

>               if (useRedAndGreen)
>                  canvas.setTextColor(Color.green);
>               else
>                  canvas.setTextColor(Color.blue);

> it is possible that just after the thread tests the value of `useRedAndGreen`, the other thread butts in and changes the value of `useRedAndGreen`. Then the blinker thread resumes and changes the text color based on the value of `useRedAndGreen` that it saw. However, that value is no longer valid, and the thread changes the text to an incorrect color. The state of the applet has become inconsistent. The variables say the color should be one thing, but the actual color is different. It's not a big deal here, but there are cases where something like this -- even if it happens very, very rarely -- could be a really big deal.

> The complete source code for this example is in the file BlinkingHelloWorld2.java.

> In the rest of this section, I will try to explain the most advanced aspect of synchronization, the `wait()` and `notify()` methods. These methods are defined in the `Object` class, and so they can be used with any object. In order to legally call an object's `wait()` method, a thread must hold that object's lock. So `wait()` is usually called only in `synchronized` methods and statements.

> A thread calls an object's `wait()` method when it wants to wait for some event to occur. (While it is waiting, it releases its hold on the lock, so that other threads can run.) Some other thread must call the same object's `notify()` method when the event occurs. When an object's `notify()` method is called, any threads that are waiting on that object will wake up and can continue. Obviously, this requires close coordination between several threads, which means very careful programming.

> If `notify()` is never called, it's possible that a waiting thread might wait forever. You can avoid this with good programming, but you can also put a time limit on how long the thread will wait. This is done by passing a parameter to the `wait()` method specifying the maximum number of milliseconds that the thread will wait. If `notify()` has not been called by the end of that time period, the thread will wake up anyway.

> As with an earlier example on this page, use of the `wait()` method requires a `try...catch` statement. Here are two methods that can be called to wait indefinitely or for a specified time period:

>              synchronized void waitDelay(int milliseconds) {
>                    // Pause for the specified number of milliseconds OR
>                    // until the notify() method is called by some other thread.
>                 try {
>                    wait(milliseconds);
>                 }
>                 catch (InterruptedException e) {
>                 }
>              }

>              synchronized void waitDelay() {
>                    // Pause until the notify() method is called
>                    // by some other thread.
>                 try {
>                    wait();
>                 }
>                 catch (InterruptedException e) {
>                 }
>              }

> The first of these can be used as a kind of interruptable delay. A thread that calls it will pause for the specified number of milliseconds, unless a call to `notify()` occurs in the meantime. I use this `waitDelay()` method in the `run()` method of the `BlinkingHelloWorld2` applet. Whenever I set the `status` variable in that applet to `TERMINATE`, I call `notify()`. If the thread is in the middle of a `waitDelay()`, this will wake it up. Suppose you click on the "Stop!" button just after the `runner` thread calls `waitDelay(300)`. Because of the call to `notify()`, the runner thread wakes up and terminates immediately, instead of continuing to sleep for 300 milliseconds before terminating. This avoids a noticeable delay between the time you click on the button and the time that its name changes back to "Blink!". However, this is still a pretty trivial use of `wait()` and `notify()`. The final example in this section shows how to use them in a non-trivial way. It also provides an example of using an off-screen canvas to do smooth animation. Here's the last "Hello World" you'll see in these notes:

> Sorry, but your browser
> doesn't support Java.

> The complete source code for this applet can be found in the file ScrollingHelloWorld.java. I'll only look at a few aspects of it here.

> The thread that animates this applet runs continually as long as this page is visible. The thread is created when the applet is first started, and it is stopped when the applet is destroyed. However, during periods when the applet is stopped, the thread is not actively running. It is just waiting to be notified when the applet is restarted. This behavior is programmed using the applet's `wait()` and `notify()` methods.

> The `runner` thread in this applet has three possible statuses: `GO` to tell it to run the animation; `TERMINATE` to tell it to terminate because the applet is about to be destroyed; and `SUSPEND` to tell it that the applet has been stopped, and that it should go to sleep and wait for the applet to be restarted. The applet's `start()` method sets the status to `GO`. If the thread does not yet exist, it is created and started. Otherwise, the existing thread is notified that the value of `status` has changed. This will wake up a thread that has been put to sleep by a previous call to `stop()`:

>              synchronized public void start() {
>                    // Called when the applet is being started or restarted.
>                    // Create a new thread or restart the existing thread.
>                 status = GO;
>                 if (runner == null || ! runner.isAlive()) {
>                        // Thread doesn't yet exist or has died for some reason.
>                    runner = new Thread(this);
>                    runner.start();
>                 }
>                 else {         // Another thread exists and is still alive, but
>                    notify();   //   is presumably  sleeping.  Wake it up.
>                 }
>              }

> The `stop()` and destroy methods merely change the value of `status` and notify the thread that the value has changed:

>              synchronized public void stop() {
>                    // Called when the applet is about to be stopped.
>                    // Suspend the thread.
>                 status = SUSPEND;
>                 notify();
>              }

>              synchronized public void destroy() {
>                    // Called when the applet is about to be permanently
>                    // destroyed.  Stop the thread.
>                 status = TERMINATE;
>                 notify();
>              }

> The `run()` method for this example uses the following `while` loop to run the animation:

>              while (status != TERMINATE) {
>                 synchronized(this) {
>                    while (status == SUSPEND)
>                       waitDelay();
>                 }
>                 if (status == GO)
>                    nextFrame();
>                 if (status == GO)
>                    waitDelay(250);
>              }

> This loop is repeated until `status` becomes equal to `TERMINATE`. The synchronized statement in this loop,

>                 synchronized(this) {
>                    while (status == SUSPEND)
>                       waitDelay();
>                 }

> causes the thread to pause as long as the `status` is `SUSPEND`. It's good practice here to use a `while` statement rather than an `if` statement, since in general `notify()` could be called for several different reasons. Just because `notify()` has been called, it doesn't necessarily mean that the value of `status` has changed from `SUSPEND` to something else.

> You might wonder why this is synchronized. If it were not synchronized, the following sequence of events would be possible: (1) The runner thread finds that the value of `status` is `SUSPEND` and decides to call `waitDelay()`; (2) some other thread butts in, changes the value of `status` and calls `notify()`; (3) the runner thread resumes and calls `waitDelay()` after `notify()` has already been called. Then the `waitDelay()` will cause the thread to wait for a `notify()` that has already occurred and is not going to occur again. This would be a minor disaster: The animation will not properly restart, or the thread will not properly terminate. Again, in other circumstances, the disaster could be major.

[ Next Section | Previous Section | Chapter Index | Main Index ]