六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

JAVA圖文說明教程 第6講 Java的線程與Java Applet

[摘要]6.1 線程簡(jiǎn)介   隨著計(jì)算機(jī)的飛速發(fā)展,個(gè)人計(jì)算機(jī)上的操作系統(tǒng)也紛紛采用多任務(wù)和分時(shí)設(shè)計(jì),將早期只有大型計(jì)算機(jī)才具有的系統(tǒng)特性帶到了個(gè)人計(jì)算機(jī)系統(tǒng)中。一般可以在同一時(shí)間內(nèi)執(zhí)行多個(gè)程序的操作系統(tǒng)都有進(jìn)程的概念。一個(gè)進(jìn)程就是一個(gè)執(zhí)行中的程序,而每一個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間、一組系統(tǒng)資源。在...
6.1 線程簡(jiǎn)介

  隨著計(jì)算機(jī)的飛速發(fā)展,個(gè)人計(jì)算機(jī)上的操作系統(tǒng)也紛紛采用多任務(wù)和分時(shí)設(shè)計(jì),將早期只有大型計(jì)算機(jī)才具有的系統(tǒng)特性帶到了個(gè)人計(jì)算機(jī)系統(tǒng)中。一般可以在同一時(shí)間內(nèi)執(zhí)行多個(gè)程序的操作系統(tǒng)都有進(jìn)程的概念。一個(gè)進(jìn)程就是一個(gè)執(zhí)行中的程序,而每一個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間、一組系統(tǒng)資源。在進(jìn)程概念中,每一個(gè)進(jìn)程的內(nèi)部數(shù)據(jù)和狀態(tài)都是完全獨(dú)立的。Java程序通過流控制來執(zhí)行程序流,程序中單個(gè)順序的流控制稱為線程,多線程則指的是在單個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程,執(zhí)行不同的任務(wù)。多線程意味著一個(gè)程序的多行語句可以看上去幾乎在同一時(shí)間內(nèi)同時(shí)運(yùn)行。

  線程與進(jìn)程相似,是一段完成某個(gè)特定功能的代碼,是程序中單個(gè)順序的流控制;但與進(jìn)程不同的是,同類的多個(gè)線程是共享一塊內(nèi)存空間和一組系統(tǒng)資源,而線程本身的數(shù)據(jù)通常只有微處理器的寄存器數(shù)據(jù),以及一個(gè)供程序執(zhí)行時(shí)使用的堆棧。所以系統(tǒng)在產(chǎn)生一個(gè)線程,或者在各個(gè)線程之間切換時(shí),負(fù)擔(dān)要比進(jìn)程小的多,正因如此,線程被稱為輕負(fù)荷進(jìn)程(light-weight process)。一個(gè)進(jìn)程中可以包含多個(gè)線程。

  一個(gè)線程是一個(gè)程序內(nèi)部的順序控制流。
  1. 進(jìn)程:每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)程上下文) ,進(jìn)程切換的開銷大。
  2. 線程:輕量的進(jìn)程,同一類線程共享代碼和數(shù)據(jù)空間,每個(gè)線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(PC),線程切換的開銷小。
  3. 多進(jìn)程:在操作系統(tǒng)中,能同時(shí)運(yùn)行多個(gè)任務(wù)程序。
  4. 多線程:在同一應(yīng)用程序中,有多個(gè)順序流同時(shí)執(zhí)行。

  6.1.1 線程的概念模型

  Java內(nèi)在支持多線程,它的所有類都是在多線程下定義的,Java利用多線程使整個(gè)系統(tǒng)成為異步系統(tǒng)。Java中的線程由三部分組成,如圖6.1所示。

  1. 虛擬的CPU,封裝在java.lang.Thread類中。
  2. CPU所執(zhí)行的代碼,傳遞給Thread類。
  3. CPU所處理的數(shù)據(jù),傳遞給Thread類。

  圖6.1線程

  6. 1. 2 線程體(1)


  Java的線程是通過java.lang.Thread類來實(shí)現(xiàn)的。當(dāng)我們生成一個(gè)Thread類的對(duì)象之后,一個(gè)新的線程就產(chǎn)生了。

  此線程實(shí)例表示Java解釋器中的真正的線程,通過它可以啟動(dòng)線程、終止線程、線程掛起等,每個(gè)線程都是通過類Thread在Java的軟件包Java.lang中定義,它的構(gòu)造方法為:

   public Thread (ThreadGroup group,Runnable target,String name);

  其中,group 指明該線程所屬的線程組;target實(shí)際執(zhí)行線程體的目標(biāo)對(duì)象,它必須實(shí)現(xiàn)接口Runnable; name為線程名。Java中的每個(gè)線程都有自己的名稱,Java提供了不同Thread類構(gòu)造器,允許給線程指定名稱。如果name為null時(shí),則Java自動(dòng)提供唯一的名稱。
  當(dāng)上述構(gòu)造方法的某個(gè)參數(shù)為null時(shí),我們可得到下面的幾個(gè)構(gòu)造方法:

  public Thread ();
  public Thread (Runnable target);
  public Thread (Runnable target,String name);
  public Thread (String name);
  public Thread (ThreadGroup group,Runnable target);
  public Thread (ThreadGroup group,String name);

  一個(gè)類聲明實(shí)現(xiàn)Runnable接口就可以充當(dāng)線程體,在接口Runnable中只定義了一個(gè)方法 run():
       public void run();

  任何實(shí)現(xiàn)接口Runnable的對(duì)象都可以作為一個(gè)線程的目標(biāo)對(duì)象,類Thread本身也實(shí)現(xiàn)了接口Runnable,因此我們可以通過兩種方法實(shí)現(xiàn)線程體。

  (一)定義一個(gè)線程類,它繼承線程類Thread并重寫其中的方法 run(),這時(shí)在初始化這個(gè)類的實(shí)例時(shí),目標(biāo)target可為null,表示由這個(gè)實(shí)例對(duì)來執(zhí)行線程體。由于Java只支持單重繼承,用這種方法定義的類不能再繼承其它父類。

  (二)提供一個(gè)實(shí)現(xiàn)接口Runnable的類作為一個(gè)線程的目標(biāo)對(duì)象,在初始化一個(gè)Thread類或者Thread子類的線程對(duì)象時(shí),把目標(biāo)對(duì)象傳遞給這個(gè)線程實(shí)例,由該目標(biāo)對(duì)象提供線程體 run()。這時(shí),實(shí)現(xiàn)接口Runnable的類仍然可以繼承其它父類。

  每個(gè)線程都是通過某個(gè)特定Thread對(duì)象的方法run( )來完成其操作的,方法run( )稱為線程體。圖6.2表示了java線程的不同狀態(tài)以及狀態(tài)之間轉(zhuǎn)換所調(diào)用的方法。

  圖6.2 線程的狀態(tài)
    
   1. 創(chuàng)建狀態(tài)(new Thread)
  執(zhí)行下列語句時(shí),線程就處于創(chuàng)建狀態(tài):
  Thread myThread = new MyThreadClass( );
  當(dāng)一個(gè)線程處于創(chuàng)建狀態(tài)時(shí),它僅僅是一個(gè)空的線程對(duì)象,系統(tǒng)不為它分配資源。

  2. 可運(yùn)行狀態(tài)( Runnable )
  Thread myThread = new MyThreadClass( );
  myThread.start( );
  當(dāng)一個(gè)線程處于可運(yùn)行狀態(tài)時(shí),系統(tǒng)為這個(gè)線程分配了它需的系統(tǒng)資源,安排其運(yùn)行并調(diào)用線程運(yùn)行方法,這樣就使得該線程處于可運(yùn)行( Runnable )狀態(tài)。需要注意的是這一狀態(tài)并不是運(yùn)行中狀態(tài)(Running ),因?yàn)榫程也許實(shí)際上并未真正運(yùn)行。由于很多計(jì)算機(jī)都是單處理器的,所以要在同一時(shí)刻運(yùn)行所有的處于可運(yùn)行狀態(tài)的線程是不可能的,Java的運(yùn)行系統(tǒng)必須實(shí)現(xiàn)調(diào)度來保證這些線程共享處理器。
  
  3. 不可運(yùn)行狀態(tài)(Not Runnable)
  進(jìn)入不可運(yùn)行狀態(tài)的原因有如下幾條:
  1) 調(diào)用了sleep()方法;
  2) 調(diào)用了suspend()方法;
  3) 為等候一個(gè)條件變量,線程調(diào)用wait()方法;
  4) 輸入輸出流中發(fā)生線程阻塞;
  不可運(yùn)行狀態(tài)也稱為阻塞狀態(tài)(Blocked)。因?yàn)槟撤N原因(輸入/輸出、等待消息或其它阻塞情況),系統(tǒng)不能執(zhí)行線程的狀態(tài)。這時(shí)即使處理器空閑,也不能執(zhí)行該線程。

  4. 死亡狀態(tài)(Dead)
  線程的終止一般可通過兩種方法實(shí)現(xiàn):自然撤消(線程執(zhí)行完)或是被停止(調(diào)用stop()方法)。目前不推薦通過調(diào)用stop()來終止線程的執(zhí)行,而是讓線程執(zhí)行完。

  

  6. 1. 2 線程體(2)


  ◇線程體的構(gòu)造

  任何實(shí)現(xiàn)接口Runnable的對(duì)象都可以作為一個(gè)線程的目標(biāo)對(duì)象,上面已講過構(gòu)造線程體有兩種方法,下面通過實(shí)例來說明如何構(gòu)造線程體的。

  例6.1 通過繼承類Thread構(gòu)造線程體
  class SimpleThread extends Thread {
  public SimpleThread(String str) {
   super(str); //調(diào)用其父類的構(gòu)造方法
  }
  public void run() { //重寫run方法
   for (int i = 0; i < 10;="" i++)="" {="">
    System.out.println(i + " " + getName());
             //打印次數(shù)和線程的名字
    try {
      sleep((int)(Math.random() * 1000));
             //線程睡眠,把控制權(quán)交出去
    } catch (InterruptedException e) {}
  }

     System.out.println("DONE! " + getName());
             //線程執(zhí)行結(jié)束
    }
  }
  public class TwoThreadsTest {
   public static void main (String args[]) {
    new SimpleThread("First").start();
             //第一個(gè)線程的名字為First
    new SimpleThread("Second").start();
             //第二個(gè)線程的名字為Second
  }
  }

   運(yùn)行結(jié)果:
    0 First
    0 Second
    1 Second
    1 First
    2 First
    2 Second
    3 Second
    3 First
    4 First
    4 Second
    5 First
    5 Second
    6 Second
    6 First
    7 First
    7 Second
    8 Second
    9 Second
    8 First
    DONE! Second
    9 First
    DONE! First

  仔細(xì)分析一下運(yùn)行結(jié)果,會(huì)發(fā)現(xiàn)兩個(gè)線程是交錯(cuò)運(yùn)行的,感覺就象是兩個(gè)線程在同時(shí)運(yùn)行。但是實(shí)際上一臺(tái)計(jì)算機(jī)通常就只有一個(gè)CPU,在某個(gè)時(shí)刻只能是只有一個(gè)線程在運(yùn)行,而java語言在設(shè)計(jì)時(shí)就充分考慮到線程的并發(fā)調(diào)度執(zhí)行。對(duì)于程序員來說,在編程時(shí)要注意給每個(gè)線程執(zhí)行的時(shí)間和機(jī)會(huì),主要是通過讓線程睡眠的辦法(調(diào)用sleep()方法)來讓當(dāng)前線程暫停執(zhí)行,然后由其它線程來爭(zhēng)奪執(zhí)行的機(jī)會(huì)。如果上面的程序中沒有用到sleep()方法,則就是第一個(gè)線程先執(zhí)行完畢,然后第二個(gè)線程再執(zhí)行完畢。所以用活sleep()方法是學(xué)習(xí)線程的一個(gè)關(guān)鍵。


  例6.2 通過接口構(gòu)造線程體
   public class Clock extends java.applet.Applet implements Runnable {//實(shí)現(xiàn)接口
      Thread clockThread;
      public void start() {
         //該方法是Applet的方法,不是線程的方法
      if (clockThread == null) {
         clockThread = new Thread(this, "Clock");
         /*線程體是Clock對(duì)象本身,線程名字為"Clock"*/
         clockThread.start(); //啟動(dòng)線程
         }
      }

      public void run() { //run()方法中是線程執(zhí)行的內(nèi)容
         while (clockThread != null) {
         repaint(); //刷新顯示畫面
         try {
           clockThread.sleep(1000);
           //睡眠1秒,即每隔1秒執(zhí)行一次
          } catch (InterruptedException e){}
         }
      }

      public void paint(Graphics g) {
          Date now = new Date(); //獲得當(dāng)前的時(shí)間對(duì)象
          g.drawString(now.getHours() + ":" + now.getMinutes()+ ":" +now.getSeconds(), 5, 10);//顯示當(dāng)前時(shí)間
      }

      public void stop() {
        //該方法是Applet的方法,不是線程的方法
          clockThread.stop();
          clockThread = null;
      }
   }

  上面這個(gè)例子是通過每隔1秒種就執(zhí)行線程的刷新畫面功能,顯示當(dāng)前的時(shí)間;看起來的效果就是一個(gè)時(shí)鐘,每隔1秒就變化一次。由于采用的是實(shí)現(xiàn)接口Runnable的方式,所以該類Clock還繼承了Applet, Clock就可以Applet的方式運(yùn)行。



主站蜘蛛池模板: 啪啪免费看视频 | 天堂影院在线观看mv | 午夜视频国语 | 日日爱影院 | 亚洲高清一区二区三区四区 | 天天综合色网 | 人人网碰人人网超 | 欧美视频导航| 一区二区三区在线免费视频 | 欧美在线视频导航 | 日韩经典第一页 | 亚洲精品九色在线网站 | 亚洲日本欧美产综合在线 | 欧美亚洲国产日韩综合在线播放 | 手机看片日韩高清国产欧美 | 窝窝女人体国产午夜视频 | 天天弄天天干 | 欧美综合国产精品日韩一 | 青青草原伊人 | 亚洲 欧美 清纯 丝袜 另类 | 一级淫片免费看 | 亚洲国产一区二区a毛片 | 一区二区三区国产美女在线播放 | 在线观看国产久青草 | 网址大全在线免费观看 | 热99这里有精品综合久久 | 色噜噜狠狠狠色综合久 | 亚洲日本在线免费观看 | 日本高清色www | 日本高清色本免费现在观看 | 一区二区网站在线观看 | 图片区偷拍区小说区 | 亚洲欧美综合图片 | 亚洲国产日韩欧美在线a乱码 | 青娱乐欧美视频 | 色妹子影院 | 色无极在线 | 亚洲一区免费在线 | 婷婷综合久久狠狠色99h | 天天操夜夜骑 | 日韩成人免费观看 |