<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 37, comments - 8, trackbacks - 0, articles - 0

    java基礎:關于線程

    Posted on 2008-08-02 11:10 夢與橋 閱讀(403) 評論(1)  編輯  收藏 所屬分類: java基礎

    1、作用:使java應用程序同時完成多項任務,當其一個線程被阻塞時,只有那個被阻塞的線程暫停,所有其他線程繼續執行。
    2、概念:一個java程序可以包含多個線程,每個線程具有部分程序功能,能與其他線程同時執行,這種能力稱為多線程。
    3、線程只是在系統層被實現,核心編程語言需要一個特定的編程接口來實現。在java中,創建線程的方法有兩種,其一是繼承Thread類,其二是實現Runnable接口。

    繼承Thread類實例:
    class MyThread extends Thread
    {
     int count=1,num;static int COUNT=1;
     MyThread(int num)
     {
      this.num=num;
      System.out.println("創建線程"+num);
     }
     public void run()
     {
      while(true)
      {
       System.out.println("線程"+num+"統計:"+count+";總統計:"+(COUNT++));
       if((++count)>6)
        return;
      }
     }
    }
    public class Test
    {
     public static void main(String args[])
     {
      for(int i=0;i<5;i++)
       new MyThread(i).start();
     }
    }

    實現Runnable接口實例:
    class MyThread implements Runnable
    {
     int count=1,num;static int COUNT=1;
     MyThread(int num)
     {
      this.num=num;
      System.out.println("創建線程"+num);
     }
     public void run()  //覆蓋run()方法
     {
      while(true)
      {
       System.out.println("線程"+num+"統計:"+count+";總統計:"+(COUNT++));
       if((++count)>6)
        return;
      }
     }
    }
    public class Test
    {
     public static void main(String args[])
     {
      //構造線程過程:Runnable target=new MyThread();
     // 構造線程過程續:Thread myThread=new Thread(taget);
      for(int i=0;i<5;i++)
       new Thread(new MyThread(i)).start();//Thread的構造函數實現之
     }
    }

    兩種創建線程試方式的比較:
                §實現Runnable的優點:java的單一繼承機制,使用戶只能采用實現Runnable方法。
                §繼承Thread的優點:當一個run()方法體現在繼承Thread類的類中,用this指向實際控制運行的Thread實例,不需要如下控制:T hread.currentThread().jion(),而可以簡單地寫為:jion()。
                §使用 Runnable 接口來實現多線程使得我們能夠在一個類中包容所有的代碼,有利于封裝,它的缺點在于,我們只能使用一套代碼,若想創建多個線程并使各個線程執行不同的代碼,則仍必須額外創建類,如果這樣的話,在大多數情況下也許還不如直接用多個類分別繼承 Thread 來得緊湊。
    4、線程生命周期基本狀態圖:

    一個Thread對象在它的生命周期中會處于以下幾種狀態:
            §新建狀態(New Thread):線程已創建、實例化完畢,還未執行方法體run()以啟動該線程。
            §就緒狀態/可運行狀態(Runnable):已調用start方法,為該線程完成登記工作和分配資源工作。可以用isAlive()方法識別一個線程是否處于runnable狀態,若是返回true,否則返回false。
            §運行狀態(Running):線程調度器為其分配了CPU時間,處于運行狀態。
            §阻塞/掛起狀態(Wait/Block):等待某個事件發生,一旦發生就離開該狀態,進入Runnable狀態。通常在調用sleep或wait方法進入該狀態,I/O阻塞時也可進入該狀態,或發生在多線程同步訪問時,線程試圖鎖住已被另一個線程鎖住的對象。
            §終止狀態(Dead):run方法執行完畢,或非預期的異常發生導致run方法終止,使線程死亡,此時不可重新啟動,與普通對象沒有區別。

     5、一個多線程的實例:
    class NewThread implements Runnable
    {
     String name;
     Thread t;
     NewThread(String name)
     {
      this.name=name;
      t=new Thread(this,name);
      System.out.println("New thread:"+t);
      t.start();
     }
     public void run()
     {
      try
      {
       for(int i=3;i>0;i--)
        Thread.sleep(1000);//使一個線程暫停執行一段時間
      }
      catch (InterruptedException e)
      {
       System.out.println(name+"Interrupted");
      }
      System.out.println(name+"   exting.");
     }
    }
    public class Test
    {
     public static void main(String args[])
     {
      NewThread nt1=new NewThread("First");
      NewThread nt2=new NewThread("Second");
      NewThread nt3=new NewThread("Third");
      //isAlive()方法用來測試其調用的線程是否仍在運行
      System.out.println("IsAlive(First):"+nt1.t.isAlive());
      System.out.println("IsAlive(Second):"+nt2.t.isAlive());
      System.out.println("IsAlive(Third):"+nt3.t.isAlive());
      try
      {
       System.out.println("Waiting for threads to finish.");
       //等待調用jion()的線程直到結束語
       nt1.t.join();
       nt2.t.join();
       nt3.t.join();
      }
      catch (InterruptedException e)
      {
       System.out.println("Main thread Interrupted");
      }
      //isAlive()方法用來測試其調用的線程是否仍在運行
      System.out.println("IsAlive(First):"+nt1.t.isAlive());
      System.out.println("IsAlive(Second):"+nt2.t.isAlive());
      System.out.println("IsAlive(Third):"+nt3.t.isAlive());
      System.out.println("Main thread exiting.");
     }
    }
    運行結果:

    本例子實現了主線程最后結束,方法是子線程調用join()方法,讓主線程等待其結束。

    6、一個故事及和這個故事有關的線程問題:
    故事:一男仙一女妖,偶然邂逅,真情相生,從此纏綿一處,不誤正業。仙的上司聽說后,非常惱火,上告玉帝,玉帝授權給他,讓他懲治這一對仙妖冤家。他一直在想如何懲治時,一日到牢中發現,女妖正用勺子喂男仙,監獄的飯菜很差,但這一對其樂融融。他冷然一笑,走出牢房,對技術員說:“你給我編寫一個程序,置入他們腦子里面,讓一個永遠不停地喂,一個永遠不停地吃。”技術員眨了一會眼睛,“這個有兩個問題,一是喂完了一勺子后,要停下來去取,這要男仙去等;在男仙嘴中塞滿沒有咽到肚里時,舉起勺子的女妖要等,所以……”“這是你的事,你自己看著辦。”技術員眨了一下眼睛退下,回到辦公室,偶一思索,打開電腦,寫出如下程序:

    class Food
    {
     int n;
     //標志,為false不允許咬,為true允許咬
     boolean blnValue=false;
     synchronized int get()
     {
      try
      {//如果沒有食物,男仙等待
       wait();
      }
      catch (InterruptedException e)
      {
       System.out.println("InterruptedException caught");
      }
      //開吃,同時告訴女妖要盛飯了
      System.out.println("Got:"+n);
      blnValue=false;
      notify();
      return n;
     }
     synchronized void put(int n)
     {
      if(blnValue)
       try
       {//如果還沒吃完,女妖等待
        wait();
       }
       catch (InterruptedException e)
       {
        System.out.println("InterruptedException caught");
       }
       //去取食物,同時告訴男仙
       this.n=n;
       blnValue=true;
       System.out.println("Put: "+n);
       notify();
     }
    }
    class Immortal implements Runnable
    {
     Food f;
     Immortal(Food f)
     {
      this.f=f;
      new Thread(this,"Immortal").start();
     }
     public void run()
     {
      while(true)
      {
       f.get();
      }
     }

    }
    class Goblin implements Runnable
    {
     Food f;
     Goblin(Food f)
     {
      this.f=f;
      new Thread(this,"Goblin").start();
     }
     public void run()
     {
      int i=1;
      while(true)
      {
       f.put(i++);
      }
     }
    }
    class Test
    {
     public static void main(String args[])
     {
      Food f=new Food();
      new Immortal(f);
      new Goblin(f);
      System.out.println("問世間情為何物,叫人喂而不倦,吃而不倦:");
     }
    }

    技術員拿著程序去見上司,上司讓它運行一遍,他運行之。上司點了點頭,從抽屜里拿出一疊鈔票,遞給他說:“這是你的特別獎金,但是我要告訴你這不是因你的程序而發——這個程序我似曾相識啊,是因為你的這句:‘問世間情為何物,叫人喂而不倦,吃而不倦。’真是妙極了,是一種無恥的幸災樂禍者,最想吟上800遍的啊。真希望,他們你喂我吃時,圍著一圈人高唱這句啊。”“你說,這段程序你似曾相識?”“是啊,我也在學JAVA啊,挺好玩的嘛,線程我剛學了沒多久。”
    出了上司的辦公室,技術員的衣服都濕了一片,回去后想了很久,第二天辭了職。當別人問及原因,他說:“偶在這壓力太大,已經無法承受。”在一片惋惜中他離開了仙界,終于一次在酒后他說:“唉,我的那個上司沒有人性啊,我怕。”“去,瞧你說,仙哪有人性,仙有仙品。”“那他是沒有仙品了,反正是一種該有的東西他沒有。”

    7、百獸之王大宴賓客及線程優先級問題
    百獸之王,偶逢佳運,得一至寶,欣喜若狂,于是大宴賓客,以示慶賀。設宴當日,高朋滿座,良友如云,大家舉杯相碰,其聲清脆。百獸之王聽之,捻須而笑。忽然一迎賓者慌張跑來,“報告大王,不好了,一群黑壓壓的飛蟲正往這邊飛來。”“今日來者均為客,奏樂歡迎。”“來得太多了,怕我把全部的食物拿出來,也不夠招待他們的。”“奶奶個熊的,真是傳說中的乞丐飛團,待我察看一下。”
    百獸之王來到門外,搭眼一瞧,顏有所失,轉首對狐貍說:“這個事情你去處理。”“是,大王。”狐貍答應之后,眼睛咕嚕一轉,計上心來,拿出手機來。
    “喂,老兄,最近忙什么呢?”
    “鼓搗JAVA啊。”
    “功力有大增吧?”
    “還好了,嘛事啊?”
    “我有個問題,想請你幫個忙?”
    “老朋友了,好說,不過,我有很長時間沒有喝過酒了。”
    “哈哈,放心吧,今天我們大王大宴賓客,款待貴賓的十瓶酒有你一瓶。”
    “兩瓶吧。”
    “你TMD的真厲害,好吧,但你可得保證我們大王滿意。”
    “皆大歡喜,說吧,什么事?”狐貍便把大王給他的任務,添上自己的考慮說了一遍。很快,他的朋友,用java寫出了一個程序,在大門的內嵌電腦上運行之。狐貍便對著那群飛蟲說:“蜜蜂們,蝴蝶們,你們好,歡迎你們來做客。今天人這么多,這么熱鬧,我們不如做個游戲。就是,當我喊開始的時候,你們就從這個大門往里飛,一段時間,大門會自動關閉。然后,在大門里的,我們招待,在大門外的請便。”
    隨著狐貍的一聲開始,蜜蜂們,蝴蝶們就匆匆往里飛。大門關上之后,根據統計的蜜蜂、蝴蝶數量,擺桌開宴。

    宴畢,皆大歡喜,狐貍的朋友也得到兩瓶好酒。我聞聽此事,去訪狐貍的這位朋友,想看一下他的那個程序。他看了我一會,在鍵盤上調了一通,寫了一些代碼,要了我的U盤,保存到上面,遞給我說:“回去,好好看看這個。”
    回來后,我打開那個程序段,原來是有關線程優先級問題的一個小程序:
    class Animal implements Runnable
    {
     int count=0;
     Thread t;
     private volatile boolean running=true;
     public Animal(int p)
     {
      t=new Thread(this);
      t.setPriority(p);
     }
     public void run()
     {
      while(running)
      {
       count++;
      }
     }
     public void stop()
     {
      running=false;
     }
     public void start()
     {
      t.start();
     }
    }
    public class Test
    {
     public static void main(String args[])
     {
      Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
      Animal bee=new Animal(Thread.NORM_PRIORITY+2);
      Animal butterfly=new Animal(4);
      bee.start();
      butterfly.start();
      try
      {
       Thread.sleep(50000);
      }
      catch (InterruptedException e)
      {
       System.out.println("Main thread interrupted.");
      }
      bee.stop();
      butterfly.stop();
      try
      {
       bee.t.join();
       butterfly.t.join();
      }
      catch (InterruptedException e)
      {
       System.out.println("InterruptedException caught");
      }
      System.out.println("關門>>>>>>");
      System.out.println("飛來蜜蜂"+bee.count+"只.");
      System.out.println("飛來蝴蝶"+butterfly.count+"只.");
     }
    }


    8、線程同步和死鎖
     當兩個或更多線程需要訪問同一個共享資源時,須用某種方式來確保資源某一時刻只被一個線程使用,達到這個目的方式稱之為同步。java中引入了互斥鎖的概念,每個對象都對應于一個可稱為“互斥鎖”的標記,這個標記保證在任一時刻,只能有一個訪問該對象。關鍵字synchronized用來與對象的互斥鎖聯系,實現同步。凡有帶有synchronized關鍵字的方法或者代碼段,系統運行時只會為之分配一個線程。
    實例:

    class TThread extends Thread
    {
     private int sum=0;
     String str=new String("");
     public void run()
     {
      while(true)
      {
       synchronized(str)
       {
        if(sum<=10)
        {
         try
         {
          Thread.sleep(10);
         }
         catch (Exception e)
         {
          e.printStackTrace();
         }
         System.out.println(Thread.currentThread().getName()+"now sum is:"+sum++);
        }
       }
      }
     }
    }
    public class Test
    {
     public static void main(String[] args)
     {
      TThread t=new TThread();
      Thread t1=new Thread(t);
      Thread t2=new Thread(t);
      Thread t3=new Thread(t);
      Thread t4=new Thread(t);

      t1.start();
      t2.start();
      t3.start();
      t4.start();
     }
    }

    注意: java語言中提供了wait()和notify()兩個方法,這兩個方法不能被重載,并且只能在同步方法中被調用。如果程序中有多個線程競爭多個資源,可能發生死鎖。當一個線程等待由另一個線程持有的鎖,而后者正在等待已被第一個線程持有的鎖時,就會發生死鎖。Java技術不檢測也不試圖避免這種情況,因而保證不發生死鎖是程序員的責任。一個通用的法則:決定獲取鎖的次序并始終遵照這個次序,按照與獲取相反的次序釋放鎖。

    Feedback

    # re: java基礎:關于線程[未登錄]  回復  更多評論   

    2009-07-25 02:42 by ^_^
    帥!!!!!!!!!!!!!!!!!!!
    我喜歡
    主站蜘蛛池模板: 在线免费观看你懂的| 久久九九免费高清视频| 免费毛片a在线观看67194| 亚洲精品免费视频| 免费黄色电影在线观看| 亚洲日韩v无码中文字幕| 中文字幕成人免费高清在线视频 | 亚洲国产精品免费观看| 亚洲好看的理论片电影| 久久久久久毛片免费播放| 日韩亚洲AV无码一区二区不卡| 久久久免费的精品| 亚洲色欲或者高潮影院| 无人在线直播免费观看| 亚洲中文字幕一二三四区| 色吊丝最新永久免费观看网站| 国产精品日本亚洲777| 亚洲欧洲一区二区三区| 日韩精品无码免费专区网站| 亚洲AV无码AV男人的天堂| 69式互添免费视频| 亚洲无码一区二区三区| 免费a级黄色毛片| 国产又黄又爽又大的免费视频| 亚洲妇熟XXXX妇色黄| 青娱乐免费视频在线观看| 亚洲精品中文字幕无码A片老| 亚洲?V乱码久久精品蜜桃| 国产亚洲精品免费视频播放| 精品亚洲麻豆1区2区3区| 在线观看的免费网站| 精品在线视频免费| 久久久久亚洲AV成人无码| 在线观看成人免费视频不卡| 国产亚洲漂亮白嫩美女在线| 亚洲动漫精品无码av天堂| 成人免费视频一区| 国产啪精品视频网站免费尤物| 亚洲中文字幕人成乱码| 国产成人精品久久亚洲高清不卡 | 一级毛片在线观看免费|