📄 tij0157.html
字号:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>suspend( )</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( )</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( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
In the following two classes, you’ll see that the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run( )</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( )</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( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
releases the lock on the object as it suspends the method it’s called
within.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You’ll
also see that there are two forms of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait( ).</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( )</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( )</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( )</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( )</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( )</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( )</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( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify( )</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( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>suspend( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>resume( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Although this seems a bit strange at first – to have something
that’s exclusively for threading as part of the universal base class
– it’s essential because they manipulate the lock that’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( )</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’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( )</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( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
within a method that’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’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 “current thread not owner.”
Note that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>suspend( ),</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>resume( )</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’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( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify( )</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’t fool with someone else’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( )</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’ll see the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify( )</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’s legal for it to call
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notify( )</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’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( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is typically used when you’ve gotten to the point where you’re
waiting for some other condition, under the control of forces outside your
thread, to change and you don’t want to idly wait by inside the thread. So
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>wait( )</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( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notifyAll( )
</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 + -