epubjs
Version:
Render ePub documents in the browser, across many devices
318 lines (303 loc) • 37.6 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>HelloJava4: Netscape’s Revenge</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="HelloJava4: Netscape’s Revenge"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-2-SECT-5"/>HelloJava4: Netscape’s Revenge</h1></div></div></div><p>We have explored quite a few features of Java with the first three
versions of the <code class="literal">HelloJava</code> application.
But until now, our application has been rather passive; it has been
completely <a id="I_indexterm2_id642784" class="indexterm"/><span class="emphasis"><em>event-driven</em></span>, waiting patiently for
events to come its way and responding to the whims of the user. Now our
application is going to take some initiative—<code class="literal">HelloJava4</code> will blink!<sup>[<a id="learnjava3-CHP-2-FNOTE-4" href="#ftn.learnjava3-CHP-2-FNOTE-4" class="footnote">5</a>]</sup> Here is the code for our latest version:</p><a id="I_2_tt62"/><pre class="programlisting"> <code class="c1">//file: HelloJava4.java</code>
<code class="kn">import</code> <code class="nn">java.awt.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">java.awt.event.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">javax.swing.*</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">class</code> <code class="nc">HelloJava4</code>
<code class="o">{</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code> <code class="n">String</code><code class="o">[]</code> <code class="n">args</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">JFrame</code> <code class="n">frame</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JFrame</code><code class="o">(</code> <code class="s">"HelloJava4"</code> <code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="k">new</code> <code class="n">HelloComponent4</code><code class="o">(</code><code class="s">"Hello, Java!"</code><code class="o">)</code> <code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setDefaultCloseOperation</code><code class="o">(</code> <code class="n">JFrame</code><code class="o">.</code><code class="na">EXIT_ON_CLOSE</code> <code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setSize</code><code class="o">(</code> <code class="mi">300</code><code class="o">,</code> <code class="mi">300</code> <code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setVisible</code><code class="o">(</code> <code class="kc">true</code> <code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code>
<code class="kd">class</code> <code class="nc">HelloComponent4</code> <code class="kd">extends</code> <code class="n">JComponent</code>
<code class="kd">implements</code> <code class="n">MouseMotionListener</code><code class="o">,</code> <code class="n">ActionListener</code><code class="o">,</code> <code class="n">Runnable</code>
<code class="o">{</code>
<code class="n">String</code> <code class="n">theMessage</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">messageX</code> <code class="o">=</code> <code class="mi">125</code><code class="o">,</code> <code class="n">messageY</code> <code class="o">=</code> <code class="mi">95</code><code class="o">;</code> <code class="c1">// Coordinates of the message</code>
<code class="n">JButton</code> <code class="n">theButton</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">colorIndex</code><code class="o">;</code> <code class="c1">// Current index into someColors.</code>
<code class="kd">static</code> <code class="n">Color</code><code class="o">[]</code> <code class="n">someColors</code> <code class="o">=</code> <code class="o">{</code>
<code class="n">Color</code><code class="o">.</code><code class="na">black</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">red</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">green</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">blue</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">magenta</code> <code class="o">};</code>
<code class="kt">boolean</code> <code class="n">blinkState</code><code class="o">;</code>
<code class="kd">public</code> <code class="nf">HelloComponent4</code><code class="o">(</code> <code class="n">String</code> <code class="n">message</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">theMessage</code> <code class="o">=</code> <code class="n">message</code><code class="o">;</code>
<code class="n">theButton</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Change Color"</code><code class="o">);</code>
<code class="n">setLayout</code><code class="o">(</code> <code class="k">new</code> <code class="n">FlowLayout</code><code class="o">()</code> <code class="o">);</code>
<code class="n">add</code><code class="o">(</code> <code class="n">theButton</code> <code class="o">);</code>
<code class="n">theButton</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code>
<code class="n">addMouseMotionListener</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code>
<code class="n">Thread</code> <code class="n">t</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Thread</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code>
<code class="n">t</code><code class="o">.</code><code class="na">start</code><code class="o">();</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">paintComponent</code><code class="o">(</code> <code class="n">Graphics</code> <code class="n">g</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">g</code><code class="o">.</code><code class="na">setColor</code><code class="o">(</code><code class="n">blinkState</code> <code class="o">?</code> <code class="n">getBackground</code><code class="o">()</code> <code class="o">:</code> <code class="n">currentColor</code><code class="o">());</code>
<code class="n">g</code><code class="o">.</code><code class="na">drawString</code><code class="o">(</code><code class="n">theMessage</code><code class="o">,</code> <code class="n">messageX</code><code class="o">,</code> <code class="n">messageY</code><code class="o">);</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">mouseDragged</code><code class="o">(</code><code class="n">MouseEvent</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code>
<code class="n">messageX</code> <code class="o">=</code> <code class="n">e</code><code class="o">.</code><code class="na">getX</code><code class="o">();</code>
<code class="n">messageY</code> <code class="o">=</code> <code class="n">e</code><code class="o">.</code><code class="na">getY</code><code class="o">();</code>
<code class="n">repaint</code><code class="o">();</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">mouseMoved</code><code class="o">(</code><code class="n">MouseEvent</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code> <code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">actionPerformed</code><code class="o">(</code> <code class="n">ActionEvent</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">e</code><code class="o">.</code><code class="na">getSource</code><code class="o">()</code> <code class="o">==</code> <code class="n">theButton</code> <code class="o">)</code>
<code class="n">changeColor</code><code class="o">();</code>
<code class="o">}</code>
<code class="kd">synchronized</code> <code class="kd">private</code> <code class="kt">void</code> <code class="nf">changeColor</code><code class="o">()</code> <code class="o">{</code>
<code class="k">if</code> <code class="o">(++</code><code class="n">colorIndex</code> <code class="o">==</code> <code class="n">someColors</code><code class="o">.</code><code class="na">length</code><code class="o">)</code>
<code class="n">colorIndex</code> <code class="o">=</code> <code class="mi">0</code><code class="o">;</code>
<code class="n">setForeground</code><code class="o">(</code> <code class="n">currentColor</code><code class="o">()</code> <code class="o">);</code>
<code class="n">repaint</code><code class="o">();</code>
<code class="o">}</code>
<code class="kd">synchronized</code> <code class="kd">private</code> <code class="n">Color</code> <code class="nf">currentColor</code><code class="o">()</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">someColors</code><code class="o">[</code><code class="n">colorIndex</code><code class="o">];</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">run</code><code class="o">()</code> <code class="o">{</code>
<code class="k">try</code> <code class="o">{</code>
<code class="k">while</code><code class="o">(</code><code class="kc">true</code><code class="o">)</code> <code class="o">{</code>
<code class="n">blinkState</code> <code class="o">=</code> <code class="o">!</code><code class="n">blinkState</code><code class="o">;</code> <code class="c1">// Toggle blinkState.</code>
<code class="n">repaint</code><code class="o">();</code> <code class="c1">// Show the change.</code>
<code class="n">Thread</code><code class="o">.</code><code class="na">sleep</code><code class="o">(</code><code class="mi">300</code><code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code> <code class="k">catch</code> <code class="o">(</code><code class="n">InterruptedException</code> <code class="n">ie</code><code class="o">)</code> <code class="o">{</code> <code class="o">}</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>Compile and run this version of <code class="literal">HelloJava</code> just like the others. You’ll see that
the text does, in fact, blink. Our apologies if you find this
annoying—it’s all in the name of education.</p><div class="sect2" title="Threads"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-5.1"/>Threads</h2></div></div></div><p>All the changes we’ve made in <code class="literal">HelloJava4</code> have to do with setting up a
separate thread of execution to make the text blink. Java is a
<a id="I_indexterm2_id642876" class="indexterm"/><span class="emphasis"><em>multithreaded</em></span> language, which means
there can be many paths of execution effectively running at the same
time. A <a id="I_indexterm2_id642885" class="indexterm"/><span class="emphasis"><em>thread</em></span> is a separate flow of control
within a program. Conceptually, threads are similar to processes. Unlike
processes, multiple threads share the same program space, which means
that they can share variables and methods (but also have their own local
variables). Threads are also quite lightweight in comparison to
processes, so it’s conceivable for a single application to be running
many (perhaps hundreds or thousands) of threads concurrently.</p><p>Multithreading provides a way for an application to handle many
different tasks at the same time. It’s easy to imagine multiple things
going on at the same time in an application like a web browser. The user
could be listening to an audio clip while scrolling an image; at the
same time, the browser can be downloading another image. Multithreading
is especially useful in GUI-based applications because it improves the
interactive performance of these applications.</p><p>Unfortunately for us, programming with multiple threads can be
quite a headache. The difficulty lies in making sure routines are
implemented so they can be run concurrently by more than one thread at a
time. If a routine changes the value of multiple state variables, for
example, it may be important that those changes happen together, without
overlapping changes affecting each other. Later in this section, we’ll
examine briefly the issue of coordinating multiple threads’ access to
shared data. In other languages, synchronization of threads can be
extremely complex and error-prone. You’ll see that Java gives you
powerful tools that help you deal with many of these problems. See <a class="xref" href="ch09.html" title="Chapter 9. Threads">Chapter 9</a> for a detailed discussion of
threads.</p><p>The Java runtime system creates and manages a number of threads.
(Exactly how varies with the implementation.) We’ve already mentioned
the repaint thread, which manages <code class="literal">repaint()</code> requests and event processing for
GUI components that belong to the <code class="literal">java.awt</code> and <code class="literal">javax.swing</code> packages. Our example applications
have done most of their work in one thread. Methods such as <code class="literal">mouseDragged()</code> and <code class="literal">actionPerformed()</code> are invoked by the windowing
thread and run by its thread, on its time. Similarly, our <code class="literal">HelloComponent</code> constructor runs as part of the
main application thread (the <code class="literal">main()</code>
method). This means we are somewhat limited in the amount of processing
we do within these methods. If we were, for instance, to go into an
endless loop in our constructor, our application would never appear
because it would never finish initializing. If we want an application to
perform any extensive processing, such as animation, a lengthy
calculation, or communication, we should create separate threads for
these tasks.</p></div><div class="sect2" title="The Thread Class"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-5.2"/>The Thread Class</h2></div></div></div><p><a id="I_indexterm2_id642989" class="indexterm"/> <a id="I_indexterm2_id643002" class="indexterm"/> <a id="I_indexterm2_id643013" class="indexterm"/>As you might have guessed, threads are created and
controlled as <code class="literal">Thread</code> objects. An
instance of the <a id="I_indexterm2_id643030" class="indexterm"/><code class="literal">java.lang.Thread</code> class
corresponds to a single thread. It contains methods to start, control,
and interrupt the thread’s execution. Our plan here is to create a
<code class="literal">Thread</code> object to handle our blinking
code. We call the <code class="literal">Thread</code>’s <code class="literal">start()</code> method to begin execution. Once the
thread starts, it continues to run until it completes its work, we
interrupt it, or we stop the application.</p><p>So, how do we tell the thread which method to run? Well, the
<code class="literal">Thread</code> object is rather picky; it
always expects to execute a method called <a id="idx10108" class="indexterm"/><code class="literal">run()</code> to perform the
action of the thread. The <code class="literal">run()</code>
method can, however, with a little persuasion, be located in any class
we desire.</p><p>We specify the location of the <code class="literal">run()</code> method in one of two ways. First, the
<code class="literal">Thread</code> class itself has a method
called <code class="literal">run()</code>. One way to execute some
Java code in a separate thread is to subclass <code class="literal">Thread</code> and override its <code class="literal">run()</code> method to do our bidding. Invoking the
<code class="literal">start()</code> method of the subclass object
causes its <code class="literal">run()</code> method to execute in
a separate thread.</p><p>It’s not usually desirable to create a subclass of <code class="literal">Thread</code> to contain our <code class="literal">run()</code> method. The <code class="literal">Thread</code> class has a constructor that takes an
object as its argument. If we create a <code class="literal">Thread</code> object using this constructor and call
its <a id="I_indexterm2_id643159" class="indexterm"/><code class="literal">start()</code> method, the
<code class="literal">Thread</code> executes the <code class="literal">run()</code> method of the argument object rather
than its own. In order to accomplish this, Java needs a guarantee that
the object we are passing it does indeed contain a compatible <code class="literal">run()</code> method. We already know how to make such
a guarantee: we use an interface. Java provides an interface named
<code class="literal">Runnable</code> that must be implemented by
any class that wants to become a <code class="literal">Thread</code>.</p></div><div class="sect2" title="The Runnable Interface"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-5.3"/>The Runnable Interface</h2></div></div></div><p><a id="I_indexterm2_id643206" class="indexterm"/> <a id="I_indexterm2_id643215" class="indexterm"/>We’ve implemented the <code class="literal">Runnable</code> interface in <code class="literal">HelloComponent4</code>. To create a thread, the
<code class="literal">HelloComponent4</code> object passes itself
(<code class="literal">this</code>) to the <code class="literal">Thread</code> constructor. This means that <code class="literal">HelloComponent4</code> must implement the <code class="literal">Runnable</code> interface by implementing the
<code class="literal">run()</code> method. This method is called
automatically when the runtime system needs to start the thread.</p><p>We indicate that the class implements the interface in our class
declaration:</p><a id="I_2_tt63"/><pre class="programlisting"> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">HelloComponent4</code>
<code class="kd">extends</code> <code class="n">JComponent</code>
<code class="kd">implements</code> <code class="n">MouseMotionListener</code><code class="o">,</code> <code class="n">ActionListener</code><code class="o">,</code> <code class="n">Runnable</code> <code class="o">{...}</code></pre><p>At compile time, the Java compiler checks to make sure we abide by
this statement. We have carried through by adding an appropriate
<code class="literal">run()</code> method to <code class="literal">HelloComponent4</code>. It takes no arguments and
returns no value. Our <code class="literal">run()</code> method
accomplishes blinking by changing the color of our text a few times a
second. It’s a very short routine, but we’re going to delay looking at
it until we tie up some loose ends in dealing with the <code class="literal">Thread</code> itself.</p></div><div class="sect2" title="Starting the Thread"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-5.4"/>Starting the Thread</h2></div></div></div><p><a id="idx10087" class="indexterm"/> <a id="I_indexterm2_id643330" class="indexterm"/>We want the blinking to begin when the application starts,
so we’ll start the thread in the initialization code in <code class="literal">HelloComponent4</code>’s constructor. It takes only
two lines:</p><a id="I_2_tt64"/><pre class="programlisting"> <code class="n">Thread</code> <code class="n">t</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Thread</code><code class="o">(</code><code class="k">this</code><code class="o">);</code>
<code class="n">t</code><code class="o">.</code><code class="na">start</code><code class="o">();</code></pre><p>First, the constructor creates a new instance of <code class="literal">Thread</code>, passing it the object that contains
the <code class="literal">run()</code> method to the constructor.
Since <code class="literal">HelloComponent4</code> itself contains
our <code class="literal">run()</code> method, we pass the special
variable <code class="literal">this</code> to the constructor.
<code class="literal">this</code> always refers to our object.
After creating the new <code class="literal">Thread</code>, we
call its <code class="literal">start()</code> method to begin
execution. This, in turn, invokes <code class="literal">HelloComponent4</code>’s <code class="literal">run()</code> method in the new thread.<a id="I_indexterm2_id643418" class="indexterm"/></p></div><div class="sect2" title="Running Code in the Thread"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-5.5"/>Running Code in the Thread</h2></div></div></div><p><a id="idx10086" class="indexterm"/> <a id="idx10109" class="indexterm"/>Our <code class="literal">run()</code> method does
its job by setting the value of the variable <code class="literal">blinkState</code>. We have added <code class="literal">blinkState</code>, a Boolean variable that can have
the value <code class="literal">true</code> or <code class="literal">false</code>, to represent whether we are currently
blinking on or off:</p><a id="I_2_tt65"/><pre class="programlisting"> <code class="kt">boolean</code> <code class="n">blinkState</code><code class="o">;</code></pre><p>A <code class="literal">setColor()</code> call has been
added to our <code class="literal">paintComponent()</code> method
to handle blinking. When <code class="literal">blinkState</code>
is <code class="literal">true</code>, the call to <code class="literal">setColor()</code> draws the text in the background
color, making it disappear:</p><a id="I_2_tt66"/><pre class="programlisting"> <code class="n">g</code><code class="o">.</code><code class="na">setColor</code><code class="o">(</code><code class="n">blinkState</code> <code class="o">?</code> <code class="n">getBackground</code><code class="o">()</code> <code class="o">:</code>
<code class="n">currentColor</code><code class="o">());</code></pre><p>Here we are being very terse, using the C language-style ternary
operator to return one of two alternative color values based on the
value of <code class="literal">blinkState</code>. If <code class="literal">blinkState</code> is <code class="literal">true</code>, the value is the value returned by the
<code class="literal">getBackground()</code> method. If it is
<code class="literal">false</code>, the value is the value
returned by <code class="literal">currentColor()</code>.</p><p>Finally, we come to the <a id="I_indexterm2_id643579" class="indexterm"/><code class="literal">run()</code>
method itself:</p><a id="I_2_tt67"/><pre class="programlisting"> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">run</code><code class="o">()</code> <code class="o">{</code>
<code class="k">try</code> <code class="o">{</code>
<code class="k">while</code><code class="o">(</code> <code class="kc">true</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">blinkState</code> <code class="o">=</code> <code class="o">!</code><code class="n">blinkState</code><code class="o">;</code>
<code class="n">repaint</code><code class="o">();</code>
<code class="n">Thread</code><code class="o">.</code><code class="na">sleep</code><code class="o">(</code><code class="mi">300</code><code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code> <code class="k">catch</code> <code class="o">(</code><code class="n">InterruptedException</code> <code class="n">ie</code><code class="o">)</code> <code class="o">{}</code>
<code class="o">}</code></pre><p>Basically, <code class="literal">run()</code> is an infinite
<a id="I_indexterm2_id643609" class="indexterm"/><code class="literal">while</code> loop, which means
the loop runs continuously until the thread is terminated by the
application exiting (not a good idea in general, but it works for this
simple example).</p><p>The body of the loop does three things on each pass:</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"><p>Flips the value of <code class="literal">blinkState</code> to its opposite value using the
<a id="I_indexterm2_id643634" class="indexterm"/><a id="I_indexterm2_id643639" class="indexterm"/><code class="literal">not</code> operator
(<code class="literal">!</code>)</p></li><li class="listitem"><p>Calls <code class="literal">repaint()</code> to redraw
the text</p></li><li class="listitem"><p>Sleeps for 300 milliseconds (about a third of a second)</p></li></ul></div><p><a id="I_indexterm2_id643669" class="indexterm"/> <code class="literal">sleep()</code> is a static
method of the <code class="literal">Thread</code> class. The
method can be invoked from anywhere and has the effect of putting the
currently running thread to sleep for the specified number of
milliseconds. The effect here is to give us approximately three blinks
per second. The <code class="literal">try/catch</code> construct,
described in the next section, traps any errors in the call to the
<code class="literal">sleep()</code> method of the <code class="literal">Thread</code> class and, in this case, ignores
them.<a id="I_indexterm2_id643705" class="indexterm"/><a id="I_indexterm2_id643712" class="indexterm"/></p></div><div class="sect2" title="Exceptions"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-5.6"/>Exceptions</h2></div></div></div><p><a id="idx10062" class="indexterm"/> <a id="idx10073" class="indexterm"/> <a id="idx10110" class="indexterm"/>The <code class="literal">try/catch</code> statement
in Java handles special conditions called <a id="I_indexterm2_id643770" class="indexterm"/><span class="emphasis"><em>exceptions</em></span>. An exception is a message
that is sent, normally in response to an error, during the execution of
a statement or a method. When an exceptional condition arises, an object
is created that contains information about the particular problem or
condition. Exceptions act somewhat like events. Java stops execution at
the place where the exception occurred, and the exception object is said
to be <span class="emphasis"><em>thrown</em></span> by that section of code. Like an
event, an exception must be delivered somewhere and handled. The section
of code that receives the exception object is said to <a id="I_indexterm2_id643789" class="indexterm"/><span class="emphasis"><em>catch</em></span> the exception. An exception
causes the execution of the instigating section of code to stop abruptly
and transfers control to the code that receives the exception
object.</p><p>The <code class="literal">try/catch</code> construct allows
you to catch exceptions for a section of code. If an exception is caused
by any statement inside a <code class="literal">try</code> clause,
Java attempts to deliver the exception to the appropriate <code class="literal">catch</code> clause. A <code class="literal">catch</code> clause looks like a method declaration
with one argument and no return type.</p><a id="I_2_tt68"/><pre class="programlisting"> <code class="k">try</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code> <code class="k">catch</code> <code class="o">(</code> <code class="n">SomeExceptionType</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>If Java finds a <code class="literal">catch</code> clause
with an argument type that matches the type of the exception, that
<code class="literal">catch</code> clause is invoked. A <code class="literal">try</code> clause can have multiple <code class="literal">catch</code> clauses with different argument types;
Java chooses the appropriate one in a way that is analogous to the
selection of overloaded methods. You can catch multiple types of
exceptions from a block of code. Depending on the type of exception
thrown, the appropriate <code class="literal">catch</code> clause
is executed.</p><p>If there is no <code class="literal">try/catch</code> clause
surrounding the code, or a matching <code class="literal">catch</code> clause is not found, the exception is
thrown up to the calling method. If the exception is not caught there,
it’s thrown up to another level, and so on until the exception is
handled or the Java VM prints an error and exits. This provides a very
flexible error-handling mechanism so that exceptions in deeply nested
calls can bubble up to the surface of the call stack for handling. As a
programmer, you need to know what exceptions a particular statement can
generate. For this reason, methods in Java are required to declare the
exceptions they can throw. If a method doesn’t handle an exception
itself, it must specify that it can throw that exception so that its
calling method knows that it may have to handle it. See <a class="xref" href="ch04.html" title="Chapter 4. The Java Language">Chapter 4</a> for a complete discussion of exceptions
and the <code class="literal">try/catch</code> clause.</p><p>Why do we need a <code class="literal">try/catch</code>
clause in the <code class="literal">run()</code> method? What kind
of exception can <code class="literal">Thread</code>’s <code class="literal">sleep()</code> method throw, and why do we care about
it when we don’t seem to check for exceptions anywhere else? Under some
circumstances, <code class="literal">Thread</code>’s <code class="literal">sleep()</code> method can throw an <code class="literal">InterruptedException</code>, indicating that it was
interrupted by another thread. Since the <code class="literal">run()</code> method specified in the <code class="literal">Runnable</code> interface doesn’t declare that it can
throw an <code class="literal">InterruptedException</code>, we
must catch it ourselves, or else the compiler will complain. The
<code class="literal">try/catch</code> statement in our example
has an empty <code class="literal">catch</code> clause, which
means that it handles the exception by ignoring it. In this case, our
thread’s functionality is so simple that it doesn’t matter if it’s
interrupted (and it won’t be anyway). All the other methods we have used
either handle their own exceptions or throw only general-purpose
exceptions called <code class="literal">RuntimeException</code>s
that are assumed to be possible everywhere and don’t need to be
explicitly declared.<a id="I_indexterm2_id643983" class="indexterm"/><a id="I_indexterm2_id643990" class="indexterm"/><a id="I_indexterm2_id643997" class="indexterm"/></p></div><div class="sect2" title="Synchronization"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-5.7"/>Synchronization</h2></div></div></div><p><a id="I_indexterm2_id644011" class="indexterm"/> <a id="I_indexterm2_id644020" class="indexterm"/>At any given time, we can have lots of threads running in
an application. Unless we explicitly coordinate them, these threads will
be executing methods without any regard for what the other threads are
doing. Problems can arise when these methods share the same data. If one
method is changing the value of some variables at the same time another
method is reading these variables, it’s possible that the reading thread
might catch things in the middle and get some variables with old values
and some with new. Depending on the application, this situation could
cause a critical error.</p><p>In our <code class="literal">HelloJava</code> examples, both
our <code class="literal">paintComponent()</code> and <code class="literal">mouseDragged()</code> methods access the <code class="literal">messageX</code> and <code class="literal">messageY</code> variables. Without knowing more about
the implementation of the Java environment, we have to assume that these
methods could conceivably be called by different threads and run
concurrently. <code class="literal">paintComponent()</code> could
be called while <code class="literal">mouseDragged()</code> is in
the midst of updating <code class="literal">messageX</code> and
<code class="literal">messageY</code>. At that point, the data is
in an inconsistent state and if <code class="literal">paintComponent()</code> gets lucky, it could get the
new <code class="literal">x</code> value with the old <code class="literal">y</code> value. Fortunately, Swing does not allow
this to happen in this case because all event activity is handled by a
single thread, and we probably would not even notice if it were to
happen in this application anyway. We did, however, see another case in
our <code class="literal">changeColor()</code> and <code class="literal">currentColor()</code> methods that is representative
of the potential for a more serious “out of bounds” error.</p><p>The <code class="literal">synchronized</code> modifier tells
Java to acquire a <a id="I_indexterm2_id644130" class="indexterm"/><span class="emphasis"><em>lock</em></span> for the object that contains the
method before executing that method. Only one method in the object can
have the lock at any given time, which means that only one synchronized
method in that object can be running at a time. This allows a method to
alter data and leave it in a consistent state before a concurrently
running method is allowed to access it. When the method is done, it
releases the lock on the class.</p><p>Unlike synchronization in other languages, the <code class="literal">synchronized</code> keyword in Java provides locking
at the language level. This means there is no way that you can forget to
unlock a class. Even if the method throws an exception or the thread is
terminated, Java will release the lock. This feature makes programming
with threads in Java much easier than in other languages. See <a class="xref" href="ch09.html" title="Chapter 9. Threads">Chapter 9</a> for more details on coordinating threads
and shared data.</p><p>Whew! Well, it’s time to say goodbye to <code class="literal">HelloJava</code>. We hope that you have developed a
feel for the major features of the Java language and that this will help
you as you explore the details of programming with Java. If you are a
bit bewildered by some of the material presented here, take heart. We’ll
be covering all the major topics presented here again in their own
chapters throughout the book. This tutorial was meant to be something of
a “trial by fire” to get the important concepts and terminology into
your brain so that the next time you hear them you’ll have a head
start.</p></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.learnjava3-CHP-2-FNOTE-4" href="#learnjava3-CHP-2-FNOTE-4" class="para">5</a>] </sup>The title of this section, “Netscape’s Revenge,” refers to the
infamous <a id="I_indexterm2_id642808" class="indexterm"/><code class="literal"><BLINK></code> HTML
tag introduced with an early version of the Netscape web
browser.</p></div></div></div></body></html>