⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter14.html

📁 java 是一个很好的网络开发环境。由于它是通过解释的方法
💻 HTML
📖 第 1 页 / 共 5 页
字号:
    }
  }
  <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){}
    }
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Counter4 <font color=#0000ff>extends</font> Applet {
  <font color=#0000ff>private</font> Button start = <font color=#0000ff>new</font> Button(<font color=#004488>"Start"</font>);
  <font color=#0000ff>private</font> <font color=#0000ff>boolean</font> started = <font color=#0000ff>false</font>;
  <font color=#0000ff>private</font> Ticker[] s;
  <font color=#0000ff>private</font> <font color=#0000ff>boolean</font> isApplet = <font color=#0000ff>true</font>;
  <font color=#0000ff>private</font> <font color=#0000ff>int</font> size;
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> init() {
    <font color=#009900>// Get parameter "size" from Web page:</font>
    <font color=#0000ff>if</font>(isApplet)
      size = 
        Integer.parseInt(getParameter(<font color=#004488>"size"</font>));
    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(<font color=#0000ff>this</font>);
    start.addActionListener(<font color=#0000ff>new</font> StartL());
    add(start);
  }
  <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>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>;
    applet.size = 
      (args.length == 0 ? 5 :
        Integer.parseInt(args[0]));
    Frame aFrame = <font color=#0000ff>new</font> Frame(<font color=#004488>"Counter4"</font>);
    aFrame.addWindowListener(
      <font color=#0000ff>new</font> WindowAdapter() {
        <font color=#0000ff>public</font> <font color=#0000ff>void</font> windowClosing(WindowEvent e) {
          System.exit(0);
        }
      });
    aFrame.add(applet, BorderLayout.CENTER);
    aFrame.setSize(200, applet.size * 50);
    applet.init();
    applet.start();
    aFrame.setVisible(<font color=#0000ff>true</font>);
  }
} <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.</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 description:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>&lt;applet code=Counter4 width=600 height=600&gt;
&lt;param name=size value=<font color=#004488>"20"</font>&gt;
&lt;/applet&gt;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The
<A NAME="Index2462"></A><A NAME="Index2463"></A><B>param</B>,
<A NAME="Index2464"></A><A NAME="Index2465"></A><B>name</B>, and
<A NAME="Index2466"></A><A NAME="Index2467"></A><B>value</B> are all Web-page
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.</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 null-pointer exception at run time. It works fine if
you move the <B>getParameter(&#160;) </B>initialization inside of
<B>init(&#160;)</B>. The <A NAME="Index2468"></A>applet framework performs the
necessary startup to grab the parameters before entering
<B>init(&#160;)</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In addition, this code is set up to
be either an <A NAME="Index2469"></A>applet or an
<A NAME="Index2470"></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).</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.</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.</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.</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.</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.</FONT><A NAME="_Toc375545477"></A><A NAME="_Toc408018750"></A><BR></P></DIV>
<A NAME="Heading487"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Daemon threads<BR><A NAME="Index2471"></A><A NAME="Index2472"></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>)</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="Index2473"></A><A NAME="Index2474"></A><B>isDaemon(&#160;)</B>, and you
can turn the daemonhood of a thread on and off with
<A NAME="Index2475"></A><A NAME="Index2476"></A><B>setDaemon(&#160;)</B>. If a
thread is a daemon, then any threads it creates will automatically be
daemons.</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>//: 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) {
    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 finish</font>
    <font color=#009900>// their startup processes:</font>
    BufferedReader stdin =
      <font color=#0000ff>new</font> BufferedReader(
        <font color=#0000ff>new</font> InputStreamReader(System.in));
    System.out.println(<font color=#004488>"Waiting for CR"</font>);
    <font color=#0000ff>try</font> {
      stdin.readLine();
    } <font color=#0000ff>catch</font>(IOException e) {}
  }
} <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.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There&#8217;s nothing to keep the
program from terminating once <B>main(&#160;)</B> finishes its job since there
are nothing but daemon threads running. So that you can see the results of
starting all the daemon threads, <B>System.in</B> is set up to read so the
program waits for a carriage return before terminating. Without this you see
only some of the results from the creation of the daemon threads. (Try replacing
the <B>readLine(&#160;)</B> code with <B>sleep(&#160;)</B> calls of various
lengths to see this
behavior.)</FONT><A NAME="_Toc375545478"></A><A NAME="_Toc408018751"></A><BR></P></DIV>
<A NAME="Heading488"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Sharing limited resources<BR><A NAME="Index2477"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can think of a single-threaded
program as one lonely entity moving around through your problem space and doing
one thing at a time. Because there&#8217;s only one entity, you never have to
think about the problem of two entities trying to use the same resource at the
same time, like two people trying to park in the same space, walk through a door
at the same time, or even talk at the same time.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">With multithreading, things
aren&#8217;t lonely anymore, but you now have the possibility of two or more
threads trying to use the same limited resource at once. Colliding over a
resource must be prevented or else you&#8217;ll have two threads trying to
access the same bank account at the same time, print to the same printer, or

⌨️ 快捷键说明

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