java--創建多線程兩種方法的比較


【通過繼承Thread】

  一個Thread對象只能創建一個線程,即使它調用多次的.start()也會只運行一個的線程。

  【看下面的代碼 & 輸出結果】

 1 package Test;
 2 
 3 class CTest extends Thread {
 4     private int tickte = 20;
 5 
 6     public void run() {
 7         while (true) {
 8             if (tickte > 0) {
 9                 System.out.println(Thread.currentThread().getName() + " 出售票 "
10                         + tickte--);
11             } else {
12                 System.exit(0);
13             }
14         }
15     }
16 
17 }
18 
19 public class Demo3 {
20     public static void main(String[] args) {
21         // new CTest().start();
22         // new CTest().start();
23         Thread t1 = new CTest();//創建一個線程
24         t1.start();
25         t1.start();
26     }
27 }
28 
29 //
30 Thread-0 出售票 20
31 Thread-0 出售票 19
32 Thread-0 出售票 18
33 Thread-0 出售票 17
34 Thread-0 出售票 16
35 Thread-0 出售票 15
36 Thread-0 出售票 14
37 Thread-0 出售票 13
38 Thread-0 出售票 12
39 Thread-0 出售票 11
40 Thread-0 出售票 10
41 Thread-0 出售票 9
42 Thread-0 出售票 8
43 Thread-0 出售票 7
44 Thread-0 出售票 6
45 Thread-0 出售票 5
46 Thread-0 出售票 4
47 Thread-0 出售票 3
48 Thread-0 出售票 2
49 Thread-0 出售票 1


通過調用當前線程對象的名字Thread.currentThread.getName(),根據結果可以看出,只運行了一個線程

這就說明了一個問題,每創建一個Thread對象,只能創建一個線程。

下面是創建多個Thread對象。

 

package Test;

class CTest extends Thread {
    private int tickte = 20;

    public void run() {
        while (true) {
            if (tickte > 0) {
                System.out.println(Thread.currentThread().getName() + " 出售票 "
                        + tickte--);
            } else {
                System.exit(0);
            }
        }
    }

}

public class Demo3 {
    public static void main(String[] args) {
         new CTest().start();
         new CTest().start();
    }
}

 上面啟動了兩個線程對象,他們各自執行自己的互不影響。

結果:

Thread-0 出售票 20
Thread-1 出售票 20
Thread-1 出售票 19
Thread-0 出售票 19
Thread-0 出售票 18
Thread-0 出售票 17
Thread-0 出售票 16
Thread-0 出售票 15
Thread-0 出售票 14
Thread-0 出售票 13
Thread-0 出售票 12
Thread-0 出售票 11
Thread-0 出售票 10
Thread-0 出售票 9
Thread-0 出售票 8
Thread-0 出售票 7
Thread-0 出售票 6
Thread-0 出售票 5
Thread-0 出售票 4
Thread-0 出售票 3
Thread-0 出售票 2
Thread-0 出售票 1
Thread-1 出售票 18
Thread-1 出售票 17
Thread-1 出售票 16
Thread-1 出售票 15
Thread-1 出售票 14
Thread-1 出售票 13
Thread-1 出售票 12
Thread-1 出售票 11
Thread-1 出售票 10
Thread-1 出售票 9
Thread-1 出售票 8
Thread-1 出售票 7
Thread-1 出售票 6
Thread-1 出售票 5
Thread-1 出售票 4
Thread-1 出售票 3
Thread-1 出售票 2
Thread-1 出售票 1

可以看出是創建了兩個線程。他們各自執行自己的線程,互不影響。

【多個線程操作一個對象】

  

01 public class ThreadDemo9_4 
02 { 
03   public static void main(String [] args) 
04  { 
05    TestThread t = new TestThread() ; 
06 // 啟動了四個線程,並實現了資源共享的目的
07   new Thread(t).start(); 
08   new Thread(t).start();
09   new Thread(t).start();
10   new Thread(t).start();
11  } 
12 } 
13  class TestThread implements Runnable 
14 { 
15  private int tickets=20; 
16   public void run() 
17  { 
18 while(true) 
19  { 
20 if(tickets>0) 
21 System.out.println(Thread.currentThread().getName()+"出售票"+tickets--); 
22  } 
23  } 
24 }

上面通過實現Runnable的方式啟動四個進程,但是他們共同操縱同一對象,實現了資源的互斥共享。

結果:

Thread-1 出售票 10
Thread-1 出售票 8
Thread-1 出售票 7
Thread-1 出售票 6
Thread-1 出售票 5
Thread-2 出售票 9
Thread-1 出售票 4
Thread-1 出售票 2
Thread-1 出售票 1
Thread-2 出售票 3

  可以看出,雖然是兩個線程,但是操作的卻只有一個資源。但是從程序的輸出結果來看,盡管啟動了兩個線程對象,但是結果都是操縱了同一個資源,實現了資源共享的目的。

  可見,實現Runnable接口相對於繼承Thread類來說,有如下顯著的優勢:
(1)、 適合多個相同程序代碼的線程去處理同一資源的情況,把虛擬CPU(線程)同程序的代碼、數據有效分離,較好地體現了面向對象的設計思想。
(2)、 可以避免由於Java的單繼承特性帶來的局限。開發中經常碰到這樣一種情況,即:當要將已經繼承了某一個類的子類放入多線程中,由於一個類不能同時有兩個父類,所以不能用繼承Thread類的方式,那么就只能采用實現Runnable接口的方式了。
(3)、 增強了程序的健壯性,代碼能夠被多個線程共享,代碼與數據是獨立的。當多個線程的執行代碼來自同一個類的實例時,即稱它們共享相同的代碼。多個線程可以操作相同的數據,與它們的代碼無關。當共享訪問相同的對象時,即共享相同的數據。當線程被構造時,需要的代碼和數據通過一個對象作為構造函數實參傳遞進去,這個對象就是一個實現了Runnable接口的類的實例。

  可以將一個Runnable接口的實例化對象作為參數去實例化Thread類對象。在實際的開發中,希望讀者盡可能去使用Runnable接口去實現多線程機制。

 

 

 

 

 


免責聲明!

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



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