UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

72 lines (70 loc) 8.84 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>Thread Groups</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="Thread Groups"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-9-SECT-5"/>Thread Groups</h1></div></div></div><p>The <code class="literal">ThreadGroup</code> class allows us to deal with threads wholesale: we can use it to arrange threads in groups and deal with the groups as a whole. A thread group can contain other thread groups in addition to individual threads, so our arrangements can be hierarchical. Thread groups are particularly useful when we want to start a task that might create many threads of its own. By assigning the task a thread group, we can later identify and control all the task’s threads. Thread groups are also the subject of restrictions that can be imposed by the Java Security Manager, so we can restrict a thread’s behavior according to its thread group. For example, we can forbid threads in a particular group from interacting with threads in other groups. This is one way web browsers can prevent threads started by Java applets from stopping important system threads.</p><p>When we create a thread, it normally becomes part of the thread group to which the currently running thread belongs. To create a new thread group of our own, we can call the constructor:</p><a id="I_9_tt519"/><pre class="programlisting"> <code class="n">ThreadGroup</code> <code class="n">myTaskGroup</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ThreadGroup</code><code class="o">(</code><code class="s">"My Task Group"</code><code class="o">);</code></pre><p>The <code class="literal">ThreadGroup</code> constructor takes a name, which a debugger can use to help you identify the group. (You can also assign names to the threads themselves.) Once we have a group, we can put threads in the group by supplying the <code class="literal">ThreadGroup</code> object as an argument to the <code class="literal">Thread</code> constructor:</p><a id="I_9_tt520"/><pre class="programlisting"> <code class="n">Thread</code> <code class="n">myTask</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Thread</code><code class="o">(</code> <code class="n">myTaskGroup</code><code class="o">,</code> <code class="n">taskPerformer</code> <code class="o">);</code></pre><p>Here, <code class="literal">myTaskGroup</code> is the thread group, and <code class="literal">taskPerformer</code> is the target object (the <code class="literal">Runnable</code> object that performs the task). Any additional threads that <code class="literal">myTask</code> creates also belong to the <code class="literal">myTaskGroup</code> thread group.</p><div class="sect2" title="Working with ThreadGroups"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-9-SECT-5.1"/>Working with ThreadGroups</h2></div></div></div><p><a id="I_indexterm9_id718674" class="indexterm"/>The <code class="literal">ThreadGroup</code> class exists so that you can control threads in batches. It has methods that parallel the basic <code class="literal">Thread</code> control methods—even the deprecated <a id="I_indexterm9_id718696" class="indexterm"/><code class="literal">stop()</code>, <a id="I_indexterm9_id718709" class="indexterm"/><code class="literal">suspend()</code>, and <a id="I_indexterm9_id718722" class="indexterm"/><code class="literal">resume()</code>. These methods operate on all the threads in a thread group. You can also mark a thread group as a “daemon”; a daemon thread group is automatically removed when all of its children are gone. If a thread group isn’t a daemon, you have to call <a id="I_indexterm9_id718740" class="indexterm"/><code class="literal">destroy()</code> in order to remove it when it is empty.</p><p>We can set the maximum priority for threads created in a thread group by calling <a id="I_indexterm9_id718754" class="indexterm"/><code class="literal">setMaximumPriority()</code>. Thereafter, no threads can be created in the thread group with a priority to be higher than the maximum; threads that change their priority can’t set their new priority to be higher than the maximum.</p><p>Finally, you can get a list of all threads in a group. The method <a id="I_indexterm9_id718772" class="indexterm"/><code class="literal">activeCount()</code> tells you how many threads are in the group; the method <a id="I_indexterm9_id718783" class="indexterm"/><code class="literal">enumerate()</code> gives you a list of them. We used the <code class="literal">enumerate()</code> method earlier when we showed the state of all threads in the default thread group using the static <code class="literal">Thread.enumerate()</code>method. The argument to <code class="literal">enumerate()</code> is an array of <code class="literal">Threads</code> that <code class="literal">enumerate()</code> fills in with the group’s threads. Both <code class="literal">activeCount()</code> and <code class="literal">enumerate()</code> operate recursively on all thread groups that are contained in the group.</p></div><div class="sect2" title="Uncaught Exceptions"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-9-SECT-5.2"/>Uncaught Exceptions</h2></div></div></div><p><a id="idx10509" class="indexterm"/>In Java, unchecked exceptions that are not caught by any method eventually bubble up to the <code class="literal">run()</code> method of the running thread and are thrown from there. By default, Java deals with these by simply printing them to the system error stream or log and terminating the thread. However, you can specify your own “catchall” behavior for these exceptions by subclassing <a id="I_indexterm9_id718867" class="indexterm"/><code class="literal">ThreadGroup</code> and overriding the <a id="I_indexterm9_id718878" class="indexterm"/><code class="literal">uncaughtException()</code> method. When an uncaught exception is generated, it is handed to this method, which can take some action or throw it again before the thread terminates.</p><p>In Java 5.0, this pattern was extended by defining an interface, <a id="I_indexterm9_id718894" class="indexterm"/><code class="literal">Thread.UncaughtExceptionHandler</code>, and adding both per-thread and systemwide uncaught exception handlers in addition to the per-<code class="literal">ThreadGroup</code> exception handler. We can handle uncaught exceptions for a single thread like this:</p><a id="I_9_tt521"/><pre class="programlisting"> <code class="n">Thread</code> <code class="n">thread</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Thread</code><code class="o">();</code> <code class="n">thread</code><code class="o">.</code><code class="na">setUncaughtExceptionHandler</code><code class="o">(</code> <code class="k">new</code> <code class="n">Thread</code><code class="o">.</code><code class="na">UncaughtExceptionHandler</code><code class="o">()</code> <code class="o">{</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">uncaughtException</code><code class="o">(</code> <code class="n">Thread</code> <code class="n">t</code><code class="o">,</code> <code class="n">Throwable</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code> <code class="n">System</code><code class="o">.</code><code class="na">err</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="n">t</code> <code class="o">+</code> <code class="s">" threw exception: "</code> <code class="o">+</code> <code class="n">e</code> <code class="o">);</code> <code class="o">}</code> <code class="o">}</code> <code class="o">);</code></pre><p>This example prints the exception before the thread dies. We could have set the same handler on the <code class="literal">ThreadGroup</code> in the same way or assigned it for all exceptions using the static <a id="I_indexterm9_id718932" class="indexterm"/><code class="literal">Thread.setDefaultUncaughtExceptionHandler()</code> method.<a id="I_indexterm9_id718944" class="indexterm"/></p></div></div></body></html>