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

📄 tij0157.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<html><body>

<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0156.html">Prev</a> | <a href="tij0158.html">Next</a>
</td>
</tr></table>
<hr>

<H2 ALIGN=LEFT>
Blocking
<P><A NAME="Index2520"></A><A NAME="Index2521"></A><A NAME="Index2522"></A></H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">A
thread can be in any one of four <A NAME="Index2523"></A>states:</FONT><P></DIV><DIV ALIGN=LEFT><A NAME="Index2524"></A><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>New</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
the thread object has been created but it hasn&#8217;t been started yet so it
cannot run.
</FONT><LI><A NAME="Index2525"></A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	<A NAME="Index2526"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>Runnable</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
This means that a thread 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>can</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
be run when the time-slicing mechanism has CPU cycles available for the thread.
Thus, the thread might or might not be running, but there&#8217;s nothing to
prevent it from being run if the scheduler can arrange it; it&#8217;s not dead
or blocked.
</FONT><LI><A NAME="Index2527"></A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	<A NAME="Index2528"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>Dead</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
the normal way for a thread to die is by returning from its 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">method.
You can also call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>stop(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
but this throws an exception that&#8217;s a subclass of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Error</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(which means you usually don&#8217;t catch it). Remember that throwing an
exception should be a special event and not part of normal program execution;
thus the use of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>stop(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is discouraged (and it&#8217;s deprecated in Java 1.2<A NAME="Index2529"></A>).
There&#8217;s also a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>destroy(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method (which has never been implemented) that you should never call if you can
avoid it since it&#8217;s drastic and doesn&#8217;t release object locks.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>	Blocked</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
the thread could be run but there&#8217;s something that prevents it. While a
thread is in the blocked state the scheduler will simply skip over it and not
give it any CPU time. Until a thread re-enters the runnable state it
won&#8217;t perform any operations.
</FONT><a name="_Toc375545482"></a><a name="_Toc408018756"></a></OL><A NAME="Heading496"></A><H3 ALIGN=LEFT>
Becoming
blocked
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
blocked state is the most interesting and is worth further examination. A
thread can become blocked for five reasons:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	You&#8217;ve
put the thread to sleep by calling <A NAME="Index2530"></A><A NAME="Index2531"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(milliseconds),</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in which case it will not be run for the specified time.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	You&#8217;ve
suspended the execution of the thread with <A NAME="Index2532"></A><A NAME="Index2533"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>suspend(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
It will not become runnable again until the thread gets the <A NAME="Index2534"></A><A NAME="Index2535"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>resume(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
message.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	You&#8217;ve
suspended the execution of the thread with <A NAME="Index2536"></A><A NAME="Index2537"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
It will not become runnable again until the thread gets the <A NAME="Index2538"></A><A NAME="Index2539"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or <A NAME="Index2540"></A><A NAME="Index2541"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notifyAll(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
message. (Yes, this looks just like number 2, but there&#8217;s a distinct
difference that will be revealed.)
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	The
<A NAME="Index2542"></A><A NAME="Index2543"></A>thread
is waiting for some IO to complete.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	The
thread is trying to call a <A NAME="Index2544"></A><A NAME="Index2545"></A><A NAME="Index2546"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">method
on another object and that object&#8217;s lock is not available.
</FONT></OL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can also call <A NAME="Index2547"></A><A NAME="Index2548"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>yield(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(a method of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">class)
to voluntarily give up the CPU so that other threads can run. However, the same
thing happens if the scheduler decides that your thread has had enough time and
jumps to another thread. That is, nothing prevents the scheduler from
re-starting your thread. When a thread is blocked, there&#8217;s some reason
that it cannot continue running.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
following example shows all five ways of becoming blocked. It all exists in a
single file called 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Blocking.java,</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
but it will be examined here in discrete pieces. (You&#8217;ll notice the
&#8220;Continued&#8221; and &#8220;Continuing&#8221; tags that allow the tool
shown in Chapter 17 to piece everything together.) First, the basic framework:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Blocking.java</font>
<font color="#009900">// Demonstrates the various ways a thread</font>
<font color="#009900">// can be blocked.</font>
<font color="#0000ff">import</font> java.awt.*;
<font color="#0000ff">import</font> java.awt.event.*;
<font color="#0000ff">import</font> java.applet.*;
<font color="#0000ff">import</font> java.io.*;

<font color="#009900">//////////// The basic framework ///////////</font>
<font color="#0000ff">class</font> Blockable <font color="#0000ff">extends</font> Thread {
  <font color="#0000ff">private</font> Peeker peeker;
  <font color="#0000ff">protected</font> TextField state = <font color="#0000ff">new</font> TextField(40);
  <font color="#0000ff">protected</font> <font color="#0000ff">int</font> i;
  <font color="#0000ff">public</font> Blockable(Container c) {
    c.add(state);
    peeker = <font color="#0000ff">new</font> Peeker(<font color="#0000ff">this</font>, c);
  }
  <font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">int</font> read() { <font color="#0000ff">return</font> i; }
  <font color="#0000ff">protected</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font> update() {
    state.setText(getClass().getName()
      + " state: i = " + i);
  }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> stopPeeker() { 
    <font color="#009900">// peeker.stop(); Deprecated in Java 1.2</font>
    peeker.terminate(); <font color="#009900">// The preferred approach</font>
  }
}

<font color="#0000ff">class</font> Peeker <font color="#0000ff">extends</font> Thread {
  <font color="#0000ff">private</font> Blockable b;
  <font color="#0000ff">private</font> <font color="#0000ff">int</font> session;
  <font color="#0000ff">private</font> TextField status = <font color="#0000ff">new</font> TextField(40);
  <font color="#0000ff">private</font> <font color="#0000ff">boolean</font> stop = <font color="#0000ff">false</font>;
  <font color="#0000ff">public</font> Peeker(Blockable b, Container c) {
    c.add(status);
    <font color="#0000ff">this</font>.b = b;
    start();
  }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> terminate() { stop = <font color="#0000ff">true</font>; }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> run() {
    <font color="#0000ff">while</font> (!stop) {
      status.setText(b.getClass().getName()
        + " Peeker " + (++session)
        + "; value = " + b.read());
       <font color="#0000ff">try</font> {
        sleep(100);
      } <font color="#0000ff">catch</font> (InterruptedException e){}
    }
  }
} <font color="#009900">///:Continued </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Blockable
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">class
is meant to be a base class for all the classes in this example that
demonstrate blocking. A 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Blockable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object contains a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TextField</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
called 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>state</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that is used to display information about the object. The method that displays
this information is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>update(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
You can see it uses 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getClass(&#160;).getName(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to produce the name of the class instead of just printing it out; this is
because 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>update(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
cannot know the exact name of the class it is called for, since it will be a
class derived from 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Blockable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
indicator of change in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Blockable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int
i,
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
which will be incremented by the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method of the derived class.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There&#8217;s
a thread of class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Peeker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that is started for each 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Blockable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object, and the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Peeker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8217;s
job is to watch its associated 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Blockable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object to see changes in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>i
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">by
calling 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>read(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and reporting them in its 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>status
TextField
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.

⌨️ 快捷键说明

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