chap14.htm

来自「Thinking in Java, 2nd edition」· HTM 代码 · 共 1,236 行 · 第 1/5 页

HTM
1,236
字号
    <font color=#0000ff>public</font> <font color=#0000ff>void</font> run() {
      <font color=#0000ff>while</font> (<font color=#0000ff>true</font>) {
        <font color=#0000ff>if</font> (runFlag)
          t.setText(Integer.toString(count++));
        <font color=#0000ff>try</font> {
          sleep(100);
        } <font color=#0000ff>catch</font>(InterruptedException e) {
          System.err.println(<font color=#004488>"Interrupted"</font>);
        }
      }
    }
  }
  <font color=#0000ff>class</font> StartL <font color=#0000ff>implements</font> ActionListener {
    <font color=#0000ff>public</font> <font color=#0000ff>void</font> actionPerformed(ActionEvent e) {
      <font color=#0000ff>if</font>(!started) {
        started = <font color=#0000ff>true</font>;
        <font color=#0000ff>for</font> (<font color=#0000ff>int</font> i = 0; i &lt; s.length; i++)
          s[i].start();
      }
    }
  }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> init() {
    Container cp = getContentPane();
    cp.setLayout(<font color=#0000ff>new</font> FlowLayout());
    <font color=#009900>// Get parameter "size" from Web page:</font>
    <font color=#0000ff>if</font> (isApplet) {
      String sz = getParameter(<font color=#004488>"size"</font>);
      <font color=#0000ff>if</font>(sz != <font color=#0000ff>null</font>)
        size = Integer.parseInt(sz);
    }
    s = <font color=#0000ff>new</font> Ticker[size];
    <font color=#0000ff>for</font> (<font color=#0000ff>int</font> i = 0; i &lt; s.length; i++)
      s[i] = <font color=#0000ff>new</font> Ticker();
    start.addActionListener(<font color=#0000ff>new</font> StartL());
    cp.add(start);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Counter4 applet = <font color=#0000ff>new</font> Counter4();
    <font color=#009900>// This isn't an applet, so set the flag and</font>
    <font color=#009900>// produce the parameter values from args:</font>
    applet.isApplet = <font color=#0000ff>false</font>;
    <font color=#0000ff>if</font>(args.length != 0)
      applet.size = Integer.parseInt(args[0]);
    Console.run(applet, 200, applet.size * 50);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>Ticker</B> contains not only its
threading equipment but also the way to control and display the thread. You can
create as many threads as you want without explicitly creating the windowing
components. 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I27' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I28>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In <B>Counter4</B> there&#8217;s an array
of <B>Ticker</B> objects called <B>s</B>. For maximum flexibility, the size of
this array is initialized by reaching out into the Web page using applet
parameters. Here&#8217;s what the size parameter looks like on the page,
embedded inside the applet tag:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>&lt;param name=size value=<font color=#004488>"20"</font>&gt;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The
<A NAME="Index1910"></A><A NAME="Index1911"></A><B>param</B>,
<A NAME="Index1912"></A><A NAME="Index1913"></A><B>name</B>, and
<A NAME="Index1914"></A><A NAME="Index1915"></A><B>value</B> are all HTML
keywords. <B>name</B> is what you&#8217;ll be referring to in your program, and
<B>value</B> can be any string, not just something that resolves to a number.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I28' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I29>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You&#8217;ll notice that the
determination of the size of the array <B>s</B> is done inside
<B>init(&#160;)</B>, and not as part of an inline definition of <B>s</B>. That
is, you <I>cannot</I> say as part of the class definition (outside of any
methods):</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>int</font> size = Integer.parseInt(getParameter(<font color=#004488>"size"</font>));
Ticker[] s = <font color=#0000ff>new</font> Ticker[size];</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can compile this, but you&#8217;ll
get a strange &#8220;null-pointer exception&#8221; at run-time. It works fine if
you move the <B>getParameter(&#160;) </B>initialization inside of
<B>init(&#160;)</B>. The <A NAME="Index1916"></A>applet framework performs the
necessary startup to grab the parameters before entering <B>init(&#160;)</B>.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I29' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I30>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In addition, this code is set up to be
either an <A NAME="Index1917"></A>applet or an
<A NAME="Index1918"></A>application. When it&#8217;s an application the
<B>size</B> argument is extracted from the command line (or a default value is
provided). 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I30' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I31>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Once the size of the array is
established, new <B>Ticker</B> objects are created; as part of the <B>Ticker</B>
constructor the button and text field for each <B>Ticker </B>is added to the
applet. 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I31' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I32>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Pressing the <B>start</B> button means
looping through the entire array of <B>Ticker</B>s and calling
<B>start(&#160;)</B> for each one. Remember, <B>start(&#160;)</B> performs
necessary thread initialization and then calls <B>run(&#160;)</B> for that
thread. 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I32' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I33>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>ToggleL </B>listener simply
inverts the flag in <B>Ticker</B> and when the associated thread next takes note
it can react accordingly. 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I33' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I34>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">One value of this example is that it
allows you to easily create large sets of independent subtasks and to monitor
their behavior. In this case, you&#8217;ll see that as the number of subtasks
gets larger, your machine will probably show more divergence in the displayed
numbers because of the way that the threads are served.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I34' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I35>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can also experiment to discover how
important the <B>sleep(100)</B> is inside <B>Ticker.run(&#160;)</B>. If you
remove the <B>sleep(&#160;)</B>, things will work fine until you press a toggle
button. Then that particular thread has a false <B>runFlag</B> and the
<B>run(&#160;)</B> is just tied up in a tight infinite loop, which appears
difficult to break during multithreading, so the responsiveness and speed of the
program really bogs down.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I35' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I36>
</FONT><A NAME="_Toc375545477"></A><A NAME="_Toc481064851"></A><BR></P></DIV>
<A NAME="Heading486"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Daemon threads<BR><A NAME="Index1919"></A><A NAME="Index1920"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">A &#8220;daemon&#8221; thread is one that
is supposed to provide a general service in the background as long as the
program is running, but is not part of the essence of the program. Thus, when
all of the non-daemon threads complete, the program is terminated. Conversely,
if there are any non-daemon threads still running, the program doesn&#8217;t
terminate. (There is, for instance, a thread that runs <B>main(&#160;)</B>.)

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I36' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I37>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can find out if a thread is a daemon
by calling
<A NAME="Index1921"></A><A NAME="Index1922"></A><B>isDaemon(&#160;)</B>, and you
can turn the &#8220;daemonhood&#8221; of a thread on and off with
<A NAME="Index1923"></A><A NAME="Index1924"></A><B>setDaemon(&#160;)</B>. If a
thread is a daemon, then any threads it creates will automatically be daemons.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I37' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER14_I38>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The following example demonstrates daemon
threads:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c14:Daemons.java</font>
<font color=#009900>// Daemonic behavior.</font>
<font color=#0000ff>import</font> java.io.*;

<font color=#0000ff>class</font> Daemon <font color=#0000ff>extends</font> Thread {
  <font color=#0000ff>private</font> <font color=#0000ff>static</font> <font color=#0000ff>final</font> <font color=#0000ff>int</font> SIZE = 10;
  <font color=#0000ff>private</font> Thread[] t = <font color=#0000ff>new</font> Thread[SIZE];
  <font color=#0000ff>public</font> Daemon() { 
    setDaemon(<font color=#0000ff>true</font>);
    start();
  }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> run() {
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; SIZE; i++)
      t[i] = <font color=#0000ff>new</font> DaemonSpawn(i);
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; SIZE; i++)
      System.out.println(
        <font color=#004488>"t["</font> + i + <font color=#004488>"].isDaemon() = "</font> 
        + t[i].isDaemon());
    <font color=#0000ff>while</font>(<font color=#0000ff>true</font>) 
      yield();
  }
}

<font color=#0000ff>class</font> DaemonSpawn <font color=#0000ff>extends</font> Thread {
  <font color=#0000ff>public</font> DaemonSpawn(<font color=#0000ff>int</font> i) {
    System.out.println(
      <font color=#004488>"DaemonSpawn "</font> + i + <font color=#004488>" started"</font>);
    start();
  }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> run() {
    <font color=#0000ff>while</font>(<font color=#0000ff>true</font>) 
      yield();
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Daemons {
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) 
  <font color=#0000ff>throws</font> IOException {
    Thread d = <font color=#0000ff>new</font> Daemon();
    System.out.println(
      <font color=#004488>"d.isDaemon() = "</font> + d.isDaemon());
    <font color=#009900>// Allow the daemon threads to</font>
    <font color=#009900>// finish their startup processes:</font>
    System.out.println(<font color=#004488>"Press any key"</font>);
    System.in.read();
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>Daemon</B> thread sets its daemon
flag to &#8220;true&#8221; and then spawns a bunch of other threads to show that
they are also daemons. Then it goes into an infinite loop that calls
<B>yield(&#160;)</B> to give up control to the other processes. In an earlier
version of this program, the infinite loops would increment <B>int </B>counters,
but this seemed to bring the whole program to a stop. Using <B>yield(&#160;)</B>
makes the program quite peppy.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?