2012-12-04 67 views
1

有人可以解釋爲什麼執行後輸出這個程序是如此不同?Java 6線程 - 與「實現Runnable」和「擴展線程」不同的行爲

首先,類別: 線程擴展java.lang.Thread中

public class UsingThreadExtension extends Thread { 

    public UsingThreadExtension(String s) { 
     super(s); 
    } 

    @Override 
    public void run() { 
     for (int i=0; i<5; i++) { 
      System.out.println(i + " " + Thread.currentThread().getName()); 

      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

一個java.lang.Runnable的執行情況:

public class UsingRunnableImplementation implements Runnable { 

    @Override 
    public void run() { 
     for (int i=0; i<5; i++) { 
      System.out.println(i + " " + Thread.currentThread().getName()); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

而且主類:

public class ThreadsExample { 

    public static void main(String[] args) { 
     UsingThreadExtension threadA = new UsingThreadExtension("Thread A"); 
     UsingRunnableImplementation runnableImplementation = new UsingRunnableImplementation(); 
     Thread threadB = new Thread(runnableImplementation, "Thread B"); 

     //threadA.start(); 
     threadB.start(); 

     try { 
      //threadA.join(); 
      threadB.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     //threadA.run(); 
     threadB.run(); 

     System.out.println("Main thread says hello!"); 
    } 
} 

在這個組合輸出是這樣的:

0 Thread B 

1 Thread B 

2 Thread B 

3 Thread B 

4 Thread B 

Main thread says hello! 

和評論threadB部分,取消註釋的ThreadA後,也有一些是這樣的:

0 Thread A 

1 Thread A 

2 Thread A 

3 Thread A 

4 Thread A 

0 main 

1 main 

2 main 

3 main 

4 main 

Main thread says hello! 

誰能告訴我,到底是什麼導致這種差異?任何提示讚賞。我想,它與threadA中重載的java.lang.Thread.run()方法相關,但爲什麼threadB,在第二種情況下不運行runnable?

回答

4

第二種情況(threadA.run()): -

由於threadA是類型的參考UsingThreadExtension: -

UsingThreadExtension threadA = new UsingThreadExtension("Thread A"); 

所以調用run方法上的ThreadA這樣的: -

threadA.run(); 

將執行運行方法UsingThreadExtension只有線程。因此,線程的名稱是主要0 main, 1 main, etc.中的第二個輸出。


第一種情況(threadB.run()): -

由於threadB是類型Thread指向一個實例僅Thread參考

Thread threadB = new Thread(runnableImplementation, "Thread B"); 

所以,調用就可以了運行方法,如: -

threadB.run(); 

將執行的run()方法僅在main線程在Thread類重寫一次。但自運行()方法線程類實際上並沒有打印任何東西。因此你沒有得到任何輸出threadB.run()

3

Runnable.run()不啓動一個新線程,它只是運行該方法 - 就像任何其他方法一樣。如果你想分離一個新的線程,你總是必須使用Thread.start()(或將Runnable提交給執行者)。

+0

我想你誤解了這個問題。 OP有意在兩個線程上調用'run'。他只是想知道,爲什麼'run'方法只在'threadB'而不在'threadA'中執行。看到輸出。 –

0

當您構造Thread將一個Runnable實例傳遞給它時,它將該實例存儲在私有字段中。的java.lang.Thread默認run()方法基本上是

if(target != null) target.run(); 

所以想必在你的線程B的情況下發生的事情是,你start()線程,並且當它完成它在內部做target = null。然後,當您稍後調用線程的run()方法時,它不再具有對目標Runnable的引用,因此不會運行它。

如果反過來,首先在主線程上調用run(),然後調用start(),您會看到很多日誌記錄。

extends Thread的情況下,run()方法被直接覆蓋,所以這個空檢查被繞過。

相關問題