?? chap14.htm
字號(hào):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<!--
This document was converted from RTF source:
By rtftohtml 4.19
See http://www.sunpack.com/RTF
Filename:TIJ2.rtf
Application Directory:C:\TOOLS\RTF2HTML\
Subject:
Author:Bruce Eckel
Operator:Bruce Eckel
Document Comments:
Version Comments:
Comments:
Keywords:
Translation Date:05/21/2001
Translation Time:10:39:26
Translation Platform:Win32
Number of Output files:23
This File:Chap14.htm
SplitDepth=1
SkipNavPanel=1
SkipLeadingToc=1
SkipTrailingToc=1
GenContents=1
GenFrames=1
GenIndex=1
-->
<HEAD lang="en"><META http-equiv="Content-Type" content="text/html">
<TITLE>14: Multiple Threads</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF"><DIV ALIGN="CENTER">
<a href="http://www.MindView.net">
<img src="mindview.gif" alt="MindView Inc." BORDER = "0"></a>
<CENTER>
<FONT FACE="Verdana" size = "-1">
[ <a href="README.txt">Viewing Hints</a> ]
[ <a href="RevHist.htm">Revision History</a> ]
[ <a href="http://www.mindview.net/Books/TIJ/">Book Home Page</a> ]
[ <a href="http://www.mindview.net/Etc/MailingList.html">Free Newsletter</a> ] <br>
[ <a href="http://www.mindview.net/Seminars">Seminars</a> ]
[ <a href="http://www.mindview.net/CDs">Seminars on CD ROM</a> ]
[ <a href="http://www.mindview.net/Services">Consulting</a> ]
</FONT>
<H2><FONT FACE="Verdana">
Thinking in Java, 2nd edition, Revision 12</FONT></H2>
<H3><FONT FACE="Verdana">©2000 by Bruce Eckel</FONT></H3>
<FONT FACE="Verdana" size = "-1">
[ <a href="Chap13.htm">Previous Chapter</a> ]
[ <a href="SimpCont.htm">Short TOC</a> ]
[ <a href="Contents.htm">Table of Contents</a> ]
[ <a href="DocIdx.htm">Index</a> ]
[ <a href="Chap15.htm">Next Chapter</a> ]
</FONT>
</CENTER>
</P></DIV><A NAME="Chapter_16"></A><A NAME="_Toc375545471"></A><A NAME="_Toc477690734"></A><A NAME="_Toc481064845"></A><A NAME="Heading480"></A><FONT FACE = "Verdana"><H1 ALIGN="LEFT">
14: Multiple Threads</H1></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia" SIZE=4><backtalk:display ID=TIJ3_CHAPTER14_I0>
Objects
provide a way to divide a program into independent sections. Often, you also
need to turn a program into separate, independently running
subtasks.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Each of these independent subtasks is
called a <A NAME="Index1890"></A><A NAME="Index1891"></A><I>thread</I>, and you
program as if each thread runs by itself and has the CPU to itself. Some
underlying mechanism is actually dividing up the CPU time for you, but in
general, you don’t have to think about it, which makes programming with
multiple threads a much easier task.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I0'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER14_I1>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">A <A NAME="Index1892"></A><I>process</I>
is a self-contained running program with its own address space. A
<A NAME="Index1893"></A><I>multitasking</I> operating system is capable of
running more than one process (program) at a time, while making it look like
each one is chugging along on its own, by periodically providing CPU cycles to
each process. A thread is a single sequential flow of control within a process.
A single process can thus have multiple concurrently executing threads.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I1'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER14_I2>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There are many possible uses for
multithreading, but in general, you’ll have some part of your program tied
to a particular event or resource, and you don’t want to hang up the rest
of your program because of that. So you create a thread associated with that
event or resource and let it run independently of the main program. A good
example is a “quit” button—you don’t want to be forced
to poll the quit button in every piece of code you write in your program and yet
you want the quit button to be responsive, as if you <I>were</I> checking it
regularly. In fact, one of the most immediately compelling reasons for
multithreading is to produce a responsive user interface.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I2'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER14_I3>
</FONT><A NAME="_Toc375545472"></A><A NAME="_Toc481064846"></A><BR></P></DIV>
<A NAME="Heading481"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Responsive user interfaces<BR><A NAME="Index1894"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As a starting point, consider a program
that performs some CPU-intensive operation and thus ends up ignoring user input
and being unresponsive. This one, a combined applet/application, will simply
display the result of a running counter:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c14:Counter1.java</font>
<font color=#009900>// A non-responsive user interface.</font>
<font color=#009900>// <applet code=Counter1 width=300 height=100></font>
<font color=#009900>// </applet></font>
<font color=#0000ff>import</font> javax.swing.*;
<font color=#0000ff>import</font> java.awt.event.*;
<font color=#0000ff>import</font> java.awt.*;
<font color=#0000ff>import</font> com.bruceeckel.swing.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Counter1 <font color=#0000ff>extends</font> JApplet {
<font color=#0000ff>private</font> <font color=#0000ff>int</font> count = 0;
<font color=#0000ff>private</font> JButton
start = <font color=#0000ff>new</font> JButton(<font color=#004488>"Start"</font>),
onOff = <font color=#0000ff>new</font> JButton(<font color=#004488>"Toggle"</font>);
<font color=#0000ff>private</font> JTextField t = <font color=#0000ff>new</font> JTextField(10);
<font color=#0000ff>private</font> <font color=#0000ff>boolean</font> runFlag = <font color=#0000ff>true</font>;
<font color=#0000ff>public</font> <font color=#0000ff>void</font> init() {
Container cp = getContentPane();
cp.setLayout(<font color=#0000ff>new</font> FlowLayout());
cp.add(t);
start.addActionListener(<font color=#0000ff>new</font> StartL());
cp.add(start);
onOff.addActionListener(<font color=#0000ff>new</font> OnOffL());
cp.add(onOff);
}
<font color=#0000ff>public</font> <font color=#0000ff>void</font> go() {
<font color=#0000ff>while</font> (<font color=#0000ff>true</font>) {
<font color=#0000ff>try</font> {
Thread.sleep(100);
} <font color=#0000ff>catch</font>(InterruptedException e) {
System.err.println(<font color=#004488>"Interrupted"</font>);
}
<font color=#0000ff>if</font> (runFlag)
t.setText(Integer.toString(count++));
}
}
<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) {
go();
}
}
<font color=#0000ff>class</font> OnOffL <font color=#0000ff>implements</font> ActionListener {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> actionPerformed(ActionEvent e) {
runFlag = !runFlag;
}
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Console.run(<font color=#0000ff>new</font> Counter1(), 300, 100);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">At this point, the Swing and applet code
should be reasonably familiar from Chapter 13. The <B>go( )</B> method is
where the program stays busy: it puts the current value of <B>count</B> into
the<B> JTextField t</B>, then increments <B>count</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I3'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER14_I4>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Part of the infinite loop inside
<B>go( )</B> is to call <B>sleep( )</B>.
<A NAME="Index1895"></A><B>sleep( )</B> must be associated with a
<A NAME="Index1896"></A><B>Thread</B> object, and it turns out that every
application has <I>some</I> thread associated with it. (Indeed, Java is based on
threads and there are always some running along with your application.) So
regardless of whether you’re explicitly using threads, you can produce the
current thread used by your program with <B>Thread </B>and the static
<B>sleep( )</B> method.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I4'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER14_I5>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that <B>sleep( )</B> can throw
an <A NAME="Index1897"></A><B>InterruptedException</B>, although throwing such
an exception is considered a hostile way to break from a thread and should be
discouraged. (Once again, exceptions are for exceptional conditions, not normal
flow of control.) Interrupting a sleeping thread is included to support a future
language feature.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I5'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER14_I6>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When the <B>start</B> button is pressed,
<B>go( )</B> is invoked. On examining <B>go( )</B>, you might naively
think (as I did) that it should allow multithreading because it goes to sleep.
That is, while the method is asleep, it seems like the CPU could be busy
monitoring other button presses. But it turns out that the real problem is that
<B>go( )</B> never returns, since it’s in an infinite loop, and this
means that <B>actionPerformed( )</B> never returns. Since you’re
stuck inside <B>actionPerformed( )</B> for the first keypress, the program
can’t handle any other events. (To get out, you must somehow kill the
process; the easiest way to do this is to press Control-C in the console window,
if you started it from the console. If you start it via the browser, you have to
kill the browser window.)
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I6'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER14_I7>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The basic problem here is that
<B>go( )</B> needs to continue performing its operations, and at the same
time it needs to return so that <B>actionPerformed( )</B> can complete and
the user interface can continue responding to the user. But in a conventional
method like <B>go( )</B> it cannot continue <I>and</I> at the same time
return control to the rest of the program. This sounds like an impossible thing
to accomplish, as if the CPU must be in two places at once, but this is
precisely the illusion that threading provides.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER14_I7'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER14_I8>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The thread model (and its programming
support in Java) is a programming convenience to simplify juggling several
operations at the same time within a single program. With threads, the CPU will
pop around and give each thread some of its time. Each thread has the
consciousness of constantly having the CPU to itself, but the CPU’s time
is actually sliced between all the threads. The exception to this is if your
program is running on multiple CPUs. But one of the great things about threading
is that you are abstracted away from this layer, so your code does not need to
know whether it is actually running on a single CPU or many. Thus, threads are a
way to create transparently scalable programs.
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -