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

📄 tij0157.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>suspend(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>do
not 
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">release
the lock as they are called. You must be aware of this when working with locks.
On the other hand, the method <A NAME="Index2557"></A><A NAME="Index2558"></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">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>does</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
release the lock when it is called, which means that other <A NAME="Index2559"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods in the thread object could be called during 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">.
In the following two classes, you&#8217;ll see that 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 is fully 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in both cases, however, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Peeker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
still has full access to the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods during 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">.
This is because 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
releases the lock on the object as it suspends the method it&#8217;s called
within.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You&#8217;ll
also see that there are two forms of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;).</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
The first takes an argument in milliseconds that has the same meaning as 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">:
pause for this period of time. The difference is that in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
the object lock is released 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>and</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you can come out of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
because of 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">
as well as having the clock run out.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
second form takes no arguments, and means that the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
will continue until 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">
comes along and will not automatically terminate after a time.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">One
fairly unique aspect of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is that both methods are part of the base class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and not part of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
as are 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</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">.
Although this seems a bit strange at first &#8211; to have something
that&#8217;s exclusively for threading as part of the universal base class
&#8211; it&#8217;s essential because they manipulate the lock that&#8217;s also
part of every object. As a result, you can put 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">
inside any 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method, regardless of whether there&#8217;s any threading going on inside that
particular class. In fact, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>only</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
place you can call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is within 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 or block. If you call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
within a method that&#8217;s not 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized,</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
the program will compile, but when you run it you&#8217;ll get an <A NAME="Index2560"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>IllegalMonitorStateException</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
with the somewhat non-intuitive message &#8220;current thread not owner.&#8221;
Note that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</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">
can all be called within non-
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods since they don&#8217;t manipulate the lock.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
only for your own lock. Again, you can compile code that tries to use the wrong
lock, but it will produce the same 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>IllegalMonitorStateException</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
message as before. You can&#8217;t fool with someone else&#8217;s lock, but you
can ask another object to perform an operation that manipulates its own lock.
So one approach is to create 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 that calls 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for its own object. However, in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Notifier</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you&#8217;ll see the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
call inside a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
block:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#0000ff">synchronized</font>(wn2) {
  wn2.notify();
}</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">where
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wn2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is the object of type 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>WaitNotify2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This method, which is not part of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>WaitNotify2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
acquires the lock on the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wn2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object, at which point it&#8217;s legal for it to call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wn2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and you won&#8217;t get the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>IllegalMonitorStateException</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">///:Continuing</font>
<font color="#009900">/////////// Blocking via wait() ///////////</font>
<font color="#0000ff">class</font> WaitNotify1 <font color="#0000ff">extends</font> Blockable {
  <font color="#0000ff">public</font> WaitNotify1(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> {
        wait(1000);
      } <font color="#0000ff">catch</font> (InterruptedException e){}
    }
  }
}

<font color="#0000ff">class</font> WaitNotify2 <font color="#0000ff">extends</font> Blockable {
  <font color="#0000ff">public</font> WaitNotify2(Container c) {
    <font color="#0000ff">super</font>(c);
    <font color="#0000ff">new</font> Notifier(<font color="#0000ff">this</font>); 
  }
  <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> {
        wait();
      } <font color="#0000ff">catch</font> (InterruptedException e){}
    }
  }
}

<font color="#0000ff">class</font> Notifier <font color="#0000ff">extends</font> Thread {
  <font color="#0000ff">private</font> WaitNotify2 wn2;
  <font color="#0000ff">public</font> Notifier(WaitNotify2 wn2) {
    <font color="#0000ff">this</font>.wn2 = wn2;
    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(2000);
      } <font color="#0000ff">catch</font> (InterruptedException e){}
      <font color="#0000ff">synchronized</font>(wn2) {
        wn2.notify();
      }
    }
  }
} <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>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is typically used when you&#8217;ve gotten to the point where you&#8217;re
waiting for some other condition, under the control of forces outside your
thread, to change and you don&#8217;t want to idly wait by inside the thread. So 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
allows you to put the thread to sleep while waiting for the world to change,
and only when 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 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notifyAll(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">occurs
does the thread wake up and check for changes. Thus, it provides a way to
synchronize between threads.
</FONT><a name="_Ref368085592"></a><P></DIV>
<A NAME="Heading500"></A><H4 ALIGN=LEFT>
Blocking
on IO
<a name="PipedIO"></a><P><A NAME="Index2561"></A><A NAME="Index2562"></A></H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
a stream is waiting for some IO activity, it will automatically block. In the

⌨️ 快捷键说明

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