【Java多線程】兩種基本實現框架


 

 

Java多線程學習1——兩種基本實現框架


 

一、前言   

      當一個Java程序啟動的時候,一個線程就立刻啟動,改程序通常也被我們稱作程序的主線程。其他所有的子線程都是由主線程產生的。主線程是程序開始就執行的,並且程序最終是以主線程的結束而結束的。

      Java編寫程序都運行在在Java虛擬機(JVM)中,在JVM的內部,程序的多任務是通過線程來實現的。每用Java命令啟動一個Java應用程序,就會啟動一個JVM進程。在同一個JVM進程中,有且只有一個進程,就是它自己。在這個JVM環境中,所有程序代碼的運行都是以線程來運行。

 


二、多線程的概念 

      通常,我們接觸的簡單的程序都是單線程的,但是如果我們需要進行“多線操作”的話,就需要借助多線程來實現了,對於一個進程中的多個線程來說,多個線程共享進程的內存塊,當有新的線程產生的時候,操作系統不分配新的內存,而是讓新線程共享原有的進程塊的內存。因此,線程間的通信很容易,速度也很快。不同的進程因為處於不同的內存塊,因此進程之間的通信相對困難。

     在Java中,多線程的實現有兩種方式:繼承java.lang.Thread類;實現java.lang.Runnable接口。

 


三、繼承Thread類來實現多線程

      當一個類繼承Thread類時,在類中必須重載run()方法,同時這個run()方法也是線程的入口,在調用的過程中,通過調用start()方法來啟動新線程,其基本框架為:

 1 class 類名 extends Thread{  2 方法1;  3 方法2;  4  5 public void run(){  6 // other code…
 7 }  8 屬性1;  9 屬性2; 10 11  
12 }

        在這里,我們用一個簡單的窗口買票的例子來實現此類多線程

 1 class TestThread extends Thread  2 {  3     private String name;  4     public TestThread(String name)  5  {  6         this.name=name;  7  }  8     public void run()  9  { 10 
11         for (int i = 0; i < 7; i++) 12  { 13             if (num > 0) 14  { 15                 System.out.println(name+"正在賣票  "+"num= " + num--); 16  } 17  } 18  } 19 
20 
21     public static void main(String[] args) 22  { 23 
24         TestThread h1 = new TestThread("窗口1"); 25         TestThread h2 = new TestThread("窗口2"); 26         TestThread h3 = new TestThread("窗口3"); 27  h1.start(); 28  h2.start(); 29  h3.start(); 30  } 31 
32     private int num = 5; 33 }

      在這個簡單的例子中,可以很清楚的看到繼承Thread實現多線程的實現已經調用,本例中運行的結果為:

 1 窗口1正在賣票  num= 5
 2 窗口1正在賣票  num= 4
 3 窗口1正在賣票  num= 3
 4 窗口1正在賣票  num= 2
 5 窗口1正在賣票  num= 1
 6 窗口2正在賣票  num= 5
 7 窗口2正在賣票  num= 4
 8 窗口2正在賣票  num= 3
 9 窗口2正在賣票  num= 2
10 窗口2正在賣票  num= 1
11 窗口3正在賣票  num= 5
12 窗口3正在賣票  num= 4
13 窗口3正在賣票  num= 3
14 窗口3正在賣票  num= 2
15 窗口3正在賣票  num= 1

      並且這個結果有一定的不可預知性,我們不能夠確定線程之間執行的具體順序,同時,更為重要的,通過繼承Thread實現多線程不能夠實現資源的共享,以購票為例子,假設票的總數為5張的話,我們只能通過一個窗口來賣完這5張票,或者說,我們開設了三個窗口,但這個三個窗口都有5張票,這顯然和我們的設計理念是有點差別的。所以,實現多線程的時候,我更喜歡使用實現Runnable接口的方法。

 


四、實現Runnable接口來實現多線程

       和繼承Thread類似,當一個類實現Runnable接口時,在類中也必須重載run()方法,同時這個run()方法也是線程的入口,在調用的過程中,通過調用start()方法來啟動新線程,其基本框架為:

 1 class 類名 implements Runnable{  2 方法1;  3 方法2;  4  5 public void run(){  6 // other code…
 7 }  8 屬性1;  9 屬性2; 10 11  
12 }

         在調用的時候會稍微有一些區別,還是以簡單的窗口買票來舉例說明:

 1 class MyThread implements Runnable  2 {  3  
 4     private int ticket = 5;  //5張票
 5  
 6     public void run()  7  {  8         for (int i=0; i<=20; i++)  9  { 10             if (this.ticket > 0) 11  { 12                 System.out.println(Thread.currentThread().getName()+ "正在賣票"+this.ticket--); 13  } 14  } 15  } 16 } 17 public class TestThread { 18      
19     public static void main(String [] args) 20  { 21         MyThread my = new MyThread(); 22         new Thread(my, "1號窗口").start(); 23         new Thread(my, "2號窗口").start(); 24         new Thread(my, "3號窗口").start(); 25  } 26 }

       程序執行的結果為:

1 1號窗口正在賣票5
2 1號窗口正在賣票4
3 1號窗口正在賣票3
4 2號窗口正在賣票2
5 1號窗口正在賣票1

       於是,我們看到了我們預先設定的效果,也就是說通過實現Runnable接口的方法,我們實現的資源的共享。

 


五、小結

     在繼承Thread類實現多線程時,我們創建了三個不同的對象,所以創建的三個線程實際上是完成的三個不同的任務,所以才會相互獨立的完成;而通過實現Runable接口來實現多線程時,我們只創建了一個對象,然后實例化三個不同的線程去完成這個任務,所以相當於是共同完成任務。

     其實,其實Thread類也是實現Runnable接口的,其源代碼如下:

1 class Thread implements Runnable { 2     //
3 public void run() { 4         if (target != null) { 5  target.run(); 6  } 7  } 8 }

      Thread中的run方法其實就是調用的是Runnable接口的run方法。方法是死的,人是活的,具體使用,可以根據實際情況來選擇。如果一個類繼承Thread,則不適合資源共享。但是如果實現了Runable接口的話,則突破了Java中單繼承的限制,很容易的實現資源共享。

     多線程是Java中非常重要的部分,本文只涉及到多線程最基本的實現以及調用的部分,例如兩個例子運行可能涉及到同步的問題,運行結果可能會有所出入,今后會陸續更新一些深入的東西,希望能對后來的學習者有所幫助。

 

Reference:http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM