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

📄 tij0157.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
This is important: Note that 
</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 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>update(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
are both 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which means they require that the object lock be free.
</FONT><P></DIV>
<A NAME="Heading497"></A><H4 ALIGN=LEFT>
Sleeping</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
first test in this program is with <A NAME="Index2549"></A><A NAME="Index2550"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(&#160;):</B></FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">///:Continuing</font>
<font color="#009900">///////////// Blocking via sleep() ///////////</font>
<font color="#0000ff">class</font> Sleeper1 <font color="#0000ff">extends</font> Blockable {
  <font color="#0000ff">public</font> Sleeper1(Container c) { <font color="#0000ff">super</font>(c); }
  <font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font> run() {
    <font color="#0000ff">while</font>(<font color="#0000ff">true</font>) {
      i++;
      update();
       <font color="#0000ff">try</font> {
        sleep(1000);
      } <font color="#0000ff">catch</font> (InterruptedException e){}
    }
  }
}
  
<font color="#0000ff">class</font> Sleeper2 <font color="#0000ff">extends</font> Blockable {
  <font color="#0000ff">public</font> Sleeper2(Container c) { <font color="#0000ff">super</font>(c); }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> run() {
    <font color="#0000ff">while</font>(<font color="#0000ff">true</font>) {
      change();
       <font color="#0000ff">try</font> {
        sleep(1000);
      } <font color="#0000ff">catch</font> (InterruptedException e){}
    }
  }
  <font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font> change() {
      i++;
      update();
  }
} <font color="#009900">///:Continued </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Sleeper1</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
the entire 
</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 is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
You&#8217;ll see that the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Peeker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
associated with this object will run along merrily 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>until</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you start the thread, and then the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Peeker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
stops cold. This is one form of blocking: since 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Sleeper1.run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and once the thread starts it&#8217;s always inside 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
the method never gives up the object lock 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">
is blocked.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Sleeper2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
provides a solution by making run un-
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Only the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>change(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which means that while 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Peeker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can access the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method it needs, namely 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>read(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Here you&#8217;ll see that the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Peeker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
continues running when you start the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Sleeper2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
thread.
</FONT><P></DIV>
<A NAME="Heading498"></A><H4 ALIGN=LEFT>
Suspending
and resuming
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
next part of the example introduces the concept of suspension. 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 has a method <A NAME="Index2551"></A><A NAME="Index2552"></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">
to temporarily halt the thread and <A NAME="Index2553"></A><A NAME="Index2554"></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">
that re-starts it at the point it was halted. Presumably, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>resume(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is called by some thread outside the suspended one, and in this case
there&#8217;s a separate class called 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Resumer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that does just that. Each of the classes demonstrating suspend/resume has an
associated resumer:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">///:Continuing</font>
<font color="#009900">/////////// Blocking via suspend() ///////////</font>
<font color="#0000ff">class</font> SuspendResume <font color="#0000ff">extends</font> Blockable {
  <font color="#0000ff">public</font> SuspendResume(Container c) {
    <font color="#0000ff">super</font>(c);    
    <font color="#0000ff">new</font> Resumer(<font color="#0000ff">this</font>); 
  }
}

<font color="#0000ff">class</font> SuspendResume1 <font color="#0000ff">extends</font> SuspendResume {
  <font color="#0000ff">public</font> SuspendResume1(Container c) { <font color="#0000ff">super</font>(c);}
  <font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font> run() {
    <font color="#0000ff">while</font>(<font color="#0000ff">true</font>) {
      i++;
      update();
      suspend(); <font color="#009900">// Deprecated in Java 1.2</font>
    }
  }
}

<font color="#0000ff">class</font> SuspendResume2 <font color="#0000ff">extends</font> SuspendResume {
  <font color="#0000ff">public</font> SuspendResume2(Container c) { <font color="#0000ff">super</font>(c);}
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> run() {
    <font color="#0000ff">while</font>(<font color="#0000ff">true</font>) {
      change();
      suspend(); <font color="#009900">// Deprecated in Java 1.2</font>
    }
  }
  <font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font> change() {
      i++;
      update();
  }
}

<font color="#0000ff">class</font> Resumer <font color="#0000ff">extends</font> Thread {
  <font color="#0000ff">private</font> SuspendResume sr;
  <font color="#0000ff">public</font> Resumer(SuspendResume sr) {
    <font color="#0000ff">this</font>.sr = sr;
    start();
  }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> run() {
    <font color="#0000ff">while</font>(<font color="#0000ff">true</font>) {
       <font color="#0000ff">try</font> {
        sleep(1000);
      } <font color="#0000ff">catch</font> (InterruptedException e){}
      sr.resume(); <font color="#009900">// Deprecated in Java 1.2</font>
    }
  }
} <font color="#009900">///:Continued </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SuspendResume1</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
also has a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized
run(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method. Again, when you start this thread you&#8217;ll see that its associated 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Peeker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
gets blocked waiting for the lock to become available, which never happens.
This is fixed as before in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SuspendResume2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which does not 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronize</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
the entire 
</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 but instead uses a separate 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>change(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
should be aware that Java 1.2<A NAME="Index2555"></A>
deprecates the use of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>suspend(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>resume(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
because 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>suspend(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
holds the object&#8217;s lock and is thus <A NAME="Index2556"></A>deadlock-prone.
That is, you can easily get a number of locked objects waiting on each other,
and this will cause your program to freeze. Although you might see them used in
older programs you should not use 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>suspend(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>resume(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The proper solution is described later in this chapter.
</FONT><P></DIV>
<A NAME="Heading499"></A><H4 ALIGN=LEFT>
Wait
and notify
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
point with the first two examples is that both 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 

⌨️ 快捷键说明

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