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

📄 tij0155.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="tij0154.html">Prev</a> | <a href="tij0156.html">Next</a>
</td>
</tr></table>
<hr>

<H2 ALIGN=LEFT>
Responsive
user interfaces
<P><A NAME="Index2453"></A></H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Counter1.java</font>
<font color="#009900">// A non-responsive user interface</font>
<font color="#0000ff">package</font> c14;
<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">public</font> <font color="#0000ff">class</font> Counter1 <font color="#0000ff">extends</font> Applet {
  <font color="#0000ff">private</font> <font color="#0000ff">int</font> count = 0;
  <font color="#0000ff">private</font> Button 
    onOff = <font color="#0000ff">new</font> Button("Toggle"),
    start = <font color="#0000ff">new</font> Button("Start");
  <font color="#0000ff">private</font> TextField t = <font color="#0000ff">new</font> TextField(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() {
    add(t);
    start.addActionListener(<font color="#0000ff">new</font> StartL());
    add(start);
    onOff.addActionListener(<font color="#0000ff">new</font> OnOffL());
    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.currentThread().sleep(100);
      } <font color="#0000ff">catch</font> (InterruptedException e){}
      <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) {
    Counter1 applet = <font color="#0000ff">new</font> Counter1();
    Frame aFrame = <font color="#0000ff">new</font> Frame("Counter1");
    aFrame.addWindowListener(
      <font color="#0000ff">new</font> WindowAdapter() {
        <font color="#0000ff">public</font> <font color="#0000ff">void</font> windowClosing(WindowEvent e) {
          System.exit(0);
        }
      });
    aFrame.add(applet, BorderLayout.CENTER);
    aFrame.setSize(300,200);
    applet.init();
    applet.start();
    aFrame.setVisible(<font color="#0000ff">true</font>);
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">At
this point, the AWT and applet code should be reasonably familiar from Chapter
13. The 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>go(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method is where the program stays busy: it puts the current value of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>count</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
into the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TextField
t
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
then increments 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>count</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">Part
of the infinite loop inside 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>go(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is to call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
<A NAME="Index2454"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
must be associated with a <A NAME="Index2455"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object, and it turns out that every application has 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>some</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
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&#8217;re explicitly using threads, you can produce the current thread used
by your program with 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread.
currentThread()<A NAME="Index2456"></A></B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(a static 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)
and then call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for that thread.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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">
can throw <A NAME="Index2457"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>InterruptedException</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
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.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>start</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
button is pressed, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>go(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is invoked. And upon examining 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>go(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
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 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>go(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
never returns, since it&#8217;s in an infinite loop, and this means that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>actionPerformed(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
never returns. Since you&#8217;re stuck inside 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>actionPerformed(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for the first keypress, the program can&#8217;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.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
basic problem here is that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>go(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
needs to continue performing its operations, and at the same time it needs to
return so 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>actionPerformed(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can complete and the user interface can continue responding to the user. But in
a conventional method like 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>go(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
it cannot continue 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>and</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
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. The thread model
(and 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&#8217;s time is actually sliced between all the threads.
</FONT><P></DIV><DIV ALIGN=LEFT><A NAME="Index2458"></A><A NAME="Index2459"></A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Threading
reduces computing efficiency somewhat, but the net improvement in program
design, resource balancing, and user convenience is often quite valuable. Of
course, if you have more than one CPU, then the operating system can dedicate
each CPU to a set of threads or even a single thread and the whole program can
run much faster. Multitasking and multithreading tend to be the most reasonable
ways to utilize multiprocessor systems.
</FONT><a name="_Toc375545473"></a><a name="_Toc408018746"></a><P></DIV>
<A NAME="Heading483"></A><H3 ALIGN=LEFT>
Inheriting
from Thread
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
simplest way to create a thread is to inherit from class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which has all the wiring necessary to create and run threads. The most
important method for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which you must override to make the thread do your bidding. Thus, 
</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 the code that will be executed &#8220;simultaneously&#8221; with the other
threads in a program.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
following example creates any number of threads that it keeps track of by
assigning each thread a unique number, generated with a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
variable. The <A NAME="Index2460"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8217;s
</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 overridden to count down each time it passes through its loop and to
finish when the count is zero (at the point when 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
returns, the thread is terminated).
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: SimpleThread.java</font>
<font color="#009900">// Very simple Threading example</font>

<font color="#0000ff">public</font> <font color="#0000ff">class</font> SimpleThread <font color="#0000ff">extends</font> Thread {
  <font color="#0000ff">private</font> <font color="#0000ff">int</font> countDown = 5;
  <font color="#0000ff">private</font> <font color="#0000ff">int</font> threadNumber;
  <font color="#0000ff">private</font> <font color="#0000ff">static</font> <font color="#0000ff">int</font> threadCount = 0;
  <font color="#0000ff">public</font> SimpleThread() {
    threadNumber = ++threadCount;
    System.out.println("Making " + threadNumber);
  }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> run() {

⌨️ 快捷键说明

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