开发测试学习
目录

7.2.1显式定义线程

在我们的单线程应用程序里,我们并没有看见线程,因为Java能自动创建和控制你的线程。如果你使用了理解Java语言的浏览器,你就已经看到使用多线程的Java程序了。你也许注意到两个小程序可以同时运行,或在你移动滚动条时小程序继续执行。这并不是表明小程序是多线程的,但说明这个浏览器是多线程的。多线程应用程序(或applet)可以使用好几个执行上下文来完成它们的工 作。多线程利用了很多任务包含单独的可分离的子任务的特点。每一个线程完成一个子任务。但是,每一个线程完成子任务时还是顺序执行的。一个多线程程序允许各个线程尽快执行完它们。这种特点会有更好的实时输入反应。

7.2.2多线程例子

下面这个例子创建了三个单独的线程,它们分别打印自己的"HelloWorld":

  //Defineoursimplethreads.Theywillpauseforashorttime//
  andthen
  printouttheirnamesanddelaytimesclassTestThreadextendsThread{
    privateStringwhoami;privateintdelay;
  //Ourconstructortostorethename(whoami)//andtimetosleep(delay)
  publicTestThread(Strings,intd){
    whoami=s;
    delay=d;
    }
  //Run-thethreadmethodsimilartomain()//Whenrunisfinished,the
  threaddies.//
  Runiscalledfromthestart()methodofThread
  public void run(){
    //Trytosleepforthespecifiedtimetry{
      sleep(delay);
    }catch(InterruptedExceptione){

    }//Nowprintoutourname
  System.out.println("HelloWorld!"+whoami+""+delay);
  }
}/***Multimtest.
  Asimplemultithreadthestprogram*/
  publicclassmultitest{
    public static voidmain(Stringargs[]){
      TestThreadt1,t2,t3;//Createourtest
  threadst1=newTestThread("Thread1",(int)(Math.readom()*2000));
  t2= new TestThread("Thread2",(int)(Math.readom()*2000));
  t3=new TestThread("Thread3",(int)(Math.readom()*2000));
  //Starteachofthethreadst1.start();
  t2.start();
  t3.start();
  }
  }

7.2.3启动一个线程

程序启动时总是调用main()函数,因此main()是我们创建和启动线程的地方: t1=newTestThread("Thread1",(int)(Math.readom()*2000)); 这一行创建了一个新的线程。后面的两个参数传递了线程的名称和线程在打印信息?reg;前的延时时间。因为我们直接控制线程,我们必须直接启动它:t1.start();

7.2.4操作线程

如果创建线程正常,t1应包含一个有效的执行线程。我们在线程的run()函数里控制线程。一?copy;我们进入run()函数,我们便可执行里面的任何程序。run()好象main()一样。 run()执行完,这个线程也就结束了。在这个例子里,我们试着延迟一个随机的时间(通过参数传递?)sleep(delay); sleep()函数只是简单地告诉线程休息多少个毫秒时间。 如果你想推迟一个线程的执行,你应使用sleep()函数。当线程睡眠是sleep()并不占用系统资源。其它线程可继续工作。一?copy;延迟时间完毕,它将打印"HelloWorld"和线程名称及延迟时间。

7.2.5暂停一个线程

我们经常需要挂起一个线程而不指定多少时间。例如,如果你创建了一个含有动画线程的小程序。也许你让用户暂停动画至到他们想恢复为止。你并不想将动画线程仍调,但想让它停止。象这种类似的线程你可用suspend()函数来控制:t1.suspend();这个函数并不永久地停止了线程,你还可用resume()函数重新激活线程:t1.resume();

7.2.6停止一个线程

线程的最后一个控制是停止函数stop()。我们用它来停止线程的执行:t1.stop(); 注意:这并没有消灭这个线程,但它停止了线程的执行。并且这个线程不能用t1.start()重新启动。在我们的例子里,我们从来不用显式地停止一个线程。我们只简单地让它执行完而已。很多复杂的线程例子将需要我们控制每一个线程。在这种情况下会使用到stop()函数。如果需要,你可以测试你的线程是否被激活。一个线程已经启动而且没有停止被认为是激活的。t1.isAlive()如果t1是激活的,这个函数将返回true.

7.2.7动画例子

下面是一个包含动画线程的applet例子:

  import java.awt.*;
  import java.awt.image.ImageProducer;
  import java.applet.Applet;
  publicclassatest3extendsAppletimplementsRunnable{
    Imageimages[];
  MediaTrackertracker;
  intindex=0;
  Threadanimator;
  intmaxWidth,maxHeight;
  //Ouroff-screencomponentsfordoublebuffering.ImageoffScrImage;
  GraphicsoffScrGC;
  //Canwepaintyes?booleanloaded=false;
  //Initializetheapplet.Setoursizeandloadtheimagespublicvoidinit()
  [//Setupourimagemonitortracker=newMediaTracker(this);
  //SetthesizeandwidthofourappletmaxWidth=100;
  maxHeight=100;
  images=newImage[10];
  //Setupthedouble-bufferandresizeourapplet
  try{offScrImage=createImage(maxWidth,maxHeight);
  offScrGC= offScrImage.getGraphics();
  offScrGC.setColor(Color.lightGray);
  offScrGC.fillRect(0,0,maxWidth,maxHeight);
  resize(maxWidth,maxHeight);
  }catch(Exceptione){
    e.printStackTrace();
  }
  //
  loadtheanimationimagesintoanarrayfor(inti=0;i
  imageFile=newString("images/Duke/T"+String.valueOf(i+1)+".gif");
  images[i]=getImage(getDocumentBase(),imageFile)://Registerthis
  imagewiththetrackertracker.addImage(images[i],i);
  }try{//Use
  trackertomakesurealltheimagesareloadedtracker.waitForAll();
  }
  catch(InterruptedExceptione){
  }
  loaded=true;
  }
  //Paintthecurrentframe.publicvoidpaint(Graphicsg){
    if(loaded){
      g.drawImage(offScrImage,0,0,this);
  }
  }
  //Start,setupourfirstimagepublicvoidstart(){
    if(tracker.checkID
  (index)){
    offScrGC.drawImage(images[index],0,0,this);
  }animator=new
  Thread(this);
  animator.start();
  }
  //Run,dotheanimationworkhere.//Grabanimage,pause,grabthenext...
  publicvoidrun(){
    //GettheidofthecurrentthreadThreadme=
  Thread.currentThread();
  //Ifouranimatorthreadexist,andisthecurrentthread...while
  ((animatr!=null)&&(animator==me)){
    if(tracker.checkID(index)) {
      //Clearthebackgroundandgetthenextimage
  offScrGC.fillRect(0,0,100,100);
  offScrGCdrawImage(images[index],0,0,this);
  index++;//Loopbacktothe
  beginningandkeepgoingif(index>=images.length){
    index=0;
  }
}
  //Delayheresoanimationlooksnormaltry{
    animator.sleep(200);
  }catch(InterruptedExceptione){

  }//Drawthenextframerepaint();
}
}