📄 ch31.htm
字号:
this.applet = applet; this.forward = forward; } public void run() { InitCounter(); DoCount(); } protected void InitCounter() { if (forward) { count = 0; increment = 1; end = 1000; position = 120; } else { count = 1000; increment = -1; end = 0; position = 180; } } protected void DoCount() { while (count != end) { count = count + increment; String str = String.valueOf(count); applet.SetDisplayStr(str, position); try sleep(100); catch (InterruptedException e) { } } }}</PRE></BLOCKQUOTE><HR><P><IMG ALIGN=RIGHT SRC="pseudo.gif" HEIGHT=94 WIDTH=94 BORDER=1><BLOCKQUOTE>Derive the <TT>MyThread2 </TT>class from <TT>Thread</TT>.<BR> Declare the class's data fields.<BR> Declare the class's constructor.<BR> Store the constructor's parameters.<BR> Override the <TT>run()</TT> method<BR> Call the method that sets the values for this thread.<BR> Call the method that does the counting.<BR> Define the <TT>InitCounter()</TT> method.<BR> If the thread is to count forward...<BR> Set the data fields for forward counting.<BR> Else if the thread is to count backwards...<BR> Set the data fields for backwards counting.<BR> Define the <TT>DoCount()</TT> method.<BR> Loop until the counting is done.<BR> Increment the counter and set the display string.<BR> Go to sleep for one hundred milliseconds.</BLOCKQUOTE><P>When you construct a <TT>MyThread2</TT> thread object, you mustpass two values as parameters: a reference to the applet and a<TT>boolean</TT> value indicating whether the thread should countforward or backward. The thread uses the <TT>boolean</TT> valuein its <TT>InitCounter()</TT> method to set the values neededto accomplish the counting. These values are the starting countvalue (<TT>count</TT>), the counting increment (<TT>increment</TT>),the target count (<TT>end</TT>), and the position at which todisplay the count in the applet (<TT>position</TT>). Notice thatthe <TT>increment</TT> variable can be either 1 or -1. When theincrement gets added to the count, a positive <TT>increment</TT>increases the count by one, whereas a negative <TT>increment</TT>decreases the count by one.<P>In its <TT>run()</TT> method, the thread calls the applet's <TT>SetDisplayStr()</TT>method, which, as you'll soon see, is the synchronized method.In other words, if the thread isn't holding the monitor objectfor <TT>SetDisplayStr()</TT>, it cannot enter the method. Thisprevents two running instances of the <TT>MyThread2</TT> threadfrom trying to change the display string at the same time.<P>Now it's time to look at the applet that's in charge of the threads.Listing 31.7 is the applet, which is called ThreadApplet3. Thisapplet creates two objects of the <TT>MyThread2</TT> class: onethat counts forward and one that counts backward. The applet's<TT>SetDisplayStr()</TT> method is where the synchronization comesinto play because both threads will be trying to access this method.<P>When you run the applet, you'll see that when the first threadcan display its count, the string will appear closer to the topof the display area. The second thread, however, displays itscount below the first thread's. For this reason, when you getthe applet going, you can sit back and watch the two threads battleover the <TT>SetDisplayStr()</TT> method.<HR><BLOCKQUOTE><B>Listing 31.7 ThreadApplet3.java: An Applet ThatUses Thread Synchronization.<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>import java.awt.*;import java.applet.*;import MyThread2;public class ThreadApplet3 extends Applet{ MyThread2 thread1; MyThread2 thread2; String displayStr; Font font; int position; public void init() { font = new Font("TimesRoman", Font.PLAIN, 72); setFont(font); displayStr = ""; position = 120; thread1 = new MyThread2(this, true); thread2 = new MyThread2(this, false); } public void start() { if (thread1.isAlive()) thread1.resume(); else thread1.start(); if (thread2.isAlive()) thread2.resume();<BR> else thread2.start(); } public void stop() { thread1.suspend(); thread2.suspend(); } public void destroy() { thread1.stop(); thread2.stop(); } public void paint(Graphics g) { g.drawString(displayStr, 50, position); } synchronized public void SetDisplayStr(String str, int pos) { displayStr = str; position = pos; repaint(); }}</PRE></BLOCKQUOTE><HR><P><IMG ALIGN=RIGHT SRC="pseudo.gif" HEIGHT=94 WIDTH=94 BORDER=1><BLOCKQUOTE>Tell Java that the applet uses the classes in the <TT>awt</TT>package.<BR>Tell Java that the applet uses the classes in the <TT>applet</TT>package.<BR>Tell Java that the applet uses the <TT>MyThread2</TT> class.<BR>Derive the <TT>ThreadApplet3</TT> class from <TT>Applet</TT>.<BR> Declare the class's data fields, including two <TT>MyThread2</TT>objects.<BR> Override the <TT>init()</TT> method.<BR> Create and set the applet's font.<BR> Initialize the display string and display position.<BR> Create the applet's two threads.<BR> Override the <TT>start()</TT> method<BR> If the first thread is already started...<BR> Resume running the thread.<BR> Else if the first thread hasn't yet been started...<BR> Start the thread.<BR> If the second thread is already started...<BR> Resume running the thread.<BR> Else if the second thread hasn't yet been started...<BR> Start the thread.<BR> Override the <TT>stop() </TT>method.<BR> Suspend both threads.<BR> Override the <TT>destroy()</TT> method.<BR> Stop both threads.<BR> Override the <TT>paint()</TT> method.<BR> Draw the applet's display string, which is the currentcount.<BR> Define the <TT>SetDisplayStr()</TT> method as synchronized.<BR> Copy the method's parameters into the class's data fields.<BR> Force Java to redraw the applet's display.</BLOCKQUOTE><H3><A NAME="UnderstandingThreadApplet">Understanding ThreadApplet3</A></H3><P>The ThreadApplet3 applet is unique with regards to other appletsin this book because it's the only applet that takes full advantageof the applet's life-cycle stages. In the <TT>init()</TT> method,the applet creates the two threads. The different <TT>boolean</TT>values given as the constructor's second argument cause the firstthread to count forward and the second thread to count backward.<P>In the <TT>start()</TT> method, the applet calls each thread's<TT>isAlive()</TT> method to determine whether the thread hasbeen started yet. The first time <TT>start()</TT> gets called,the threads have been created in <TT>init()</TT> but haven't beenstarted. In this case, <TT>isAlive()</TT> returns <TT>false</TT>,and the applet calls each thread's <TT>start()</TT> method toget the threads rolling. If <TT>start()</TT> is not being calledfor the first time, it's because the user has switched back tothe applet from another Web page. In this case, <TT>isAlive()</TT>returns <TT>true</TT>. The applet knows that it must call thethreads' <TT>resume()</TT> method rather than <TT>start()</TT>.<P>In the <TT>stop()</TT> method, which gets called when the userswitches to another Web page, rather than stopping the threads,the applet suspends them. The threads remain suspended until theapplet calls their <TT>resume()</TT> methods, which, as you nowknow, happens in the <TT>start()</TT> method.<P>Finally, when Java calls the <TT>destroy()</TT> method, the appletis going away for good. The threads, too, should follow suit,so the applet calls each thread's <TT>stop()</TT> method.<P><CENTER><TABLE BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD><B>CAUTION</B></TD></TR><TR VALIGN=TOP><TD><BLOCKQUOTE>When programming threads, you always have to watch out for a condition known as <I>deadlock</I>. Deadlock occurs when two or more threads are waiting to gain control of a resource, but for one reason or another, the threads rely on conditions that can't be met in order to get control of the resource. To understand this situation, imagine that you have a pencil in your hand, and someone else has a pen. Now, assume that you can't release the pencil until you have the pen, and the other person can't release the pen until she has the pencil. Deadlock! A more computer-oriented example would be when one thread must access Method1 before it can release its hold on Method2, but the second thread must access Method2 before it can release its hold on Method1. Because these are mutually exclusive conditions, the threads are deadlocked and cannot run.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><H2><A NAME="Summary"><FONT SIZE=5 COLOR=#Ff0000>Summary</FONT></A></H2><P>Threads enable you to break an applet's tasks into separate flowsof execution. These subprograms seem to run concurrently thanksto the task switching that occurs in multitasking systems. Youcan create a thread from a class by implementing the <TT>Runnable</TT>interface in the class. However, you can also create a separateclass for your threads by deriving the class from <TT>Thread</TT>.Depending on how you want to use the threads, you can create andstart your threads in the applet's <TT>start()</TT> method andstop the threads in the <TT>stop()</TT> method. If you want yourthreads to retain their state when the user switches to and fromyour Web page, you should create the threads in <TT>init()</TT>,start or resume the threads in <TT>start()</TT>, suspend the threadsin <TT>stop()</TT>, and stop the threads in <TT>destroy()</TT>.Remember that if there's a chance that two or more threads maycompete for a resource, you need to protect that resource usingthread synchronization.<H2><A NAME="ReviewQuestions"><FONT SIZE=5 COLOR=#Ff0000>Review Questions</FONT></A></H2><OL><LI>How are threads similar to multitasking?<LI>What Java interface must be implemented by all threads?<LI>What thread method do you call to start a thread?<LI>What method does Java call to get a thread started?<LI>What are the two applet methods in which you'll usually stopyour threads?<LI>What's the difference between suspending and stopping a thread?<LI>How do you ensure that your threads share the computer's processorproperly?<LI>If you don't care about retaining a thread's state as theuser switches between Web pages, where in your applet should youcreate and start your threads?<LI>How can you take advantage of an applet's life cycle in orderto retain a thread's state as the user switches between Web pages.<LI>When would you use the <TT>synchronized</TT> keyword?<LI>What's a monitor object?</OL><H2><A NAME="ReviewExercises"><FONT SIZE=5 COLOR=#Ff0000>Review Exercises</FONT></A></H2><OL><LI>Modify the ThreadApplet applet so that the applet's stateis retained when switching to and from the applet's Web page.Name the new version ThreadApplet4. (You can find the solutionto this exercise in the CHAP31 folder of this book's CD-ROM.)<LI>Modify the ThreadApplet2 applet so that the thread changesthe color of three rectangles displayed in the applet (see Figure31.2). The rectangles' colors should cycle between red, green,and blue. Repeat the color cycling until the user stops the applet.Name the applet ThreadApplet5, and name the new thread class <TT>ColorThread</TT>.(You can find the solution to this exercise in the CHAP31 folderof this book's CD-ROM.)<BR><A HREF="f31-2.gif"><B> Figure 31.2 : </B><I>Your TheadApplet5 applet should look like this when running under Appletviewer.</I></A><P><LI>Modify your ThreadApplet5 applet (naming the new applet ThreadApplet6)so that it runs two threads. One thread should change the rectangles'colors to red, green, and blue, and the second thread should changethe rectangles to pink, orange, and yellow. Modify the <TT>ColorThread</TT>class from exercise 2, renaming it <TT>ColorThread2</TT>, andthen create a new thread class called <TT>ColorThread3</TT> forsetting the second set of colors. Don't forget to use thread synchronizationto prevent one thread from changing the rectangles' colors whenanother thread is already doing so. (You can find the solutionfor this exercise in the CHAP31 folder of this book's CD-ROM.)</OL><HR><HR WIDTH="100%"></P></CENTER><!-- reference library footer #1--></CENTER><IMG SRC="/images/rule.gif" WIDTH="460" HEIGHT="5" VSPACE="5"ALT="Ruler image"><br><FONT SIZE="-1">Contact <a href="mailto:reference@developer.com">reference@developer.com</a> with questions or comments.<br><a href="/legal/">Copyright 1998</a> <a href="http://www.earthweb.com" target="_top">EarthWeb Inc.</a>, All rights reserved.<BR>PLEASE READ THE <a href="/reference/usage.html">ACCEPTABLE USAGE STATEMENT</a>.<BR>Copyright 1998 Macmillan Computer Publishing. All rights reserved.</FONT></BLOCKQUOTE><!--outer table--><TD VALIGN="TOP"><!--right side ads --><a target="resource window" href="http://adserver.developer.com/cgi-bin/accipiter/adclick.exe/AREA=DCAD1.REF" alt="Click here for more info"><img src="http://adserver.developer.com/cgi-bin/accipiter/adserver.exe/AREA=DCAD1.REF" alt="Click here for more info" height="88" width="88" border="0"></a><P><a target="resource window" href="http://adserver.developer.com/cgi-bin/accipiter/adclick.exe/AREA=DCAD2.REF" alt="Click here for more info"><img src="http://adserver.developer.com/cgi-bin/accipiter/adserver.exe/AREA=DCAD2.REF" alt="Click here for more info" height="88" width="88" border="0"></a><P></td></tr></table></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -