2013-10-14 425 views
0

繼承人關於線程的代碼.....我不知道這兩個新()語句之間的區別。你能解釋一下這個線程的工作嗎?

Runnable r=new Runnable() { 
    public void run() { 
    System.out.print("Cat"); 
    } 
    }; 

    Thread t=new Thread(r) { 
    public void run() { 
    System.out.println("Dog"); 
    } 
    }; 
    t.start(); 

輸出是狗 但是爲什麼以及如何?

+0

你沒有啓動可運行 – tom

回答

3

因爲您覆蓋了Thread#run(),所以最終在您啓動線程時執行此方法。默認Thread#run()代表到達Runnable。經驗法則:提供Runnable或覆蓋Thread#run(),但不要同時做!

+1

其實經驗法則是從不創建線程的子類開始,很少有這樣做的理由 – Voo

+0

同意,將'Runnable'傳遞給'Thread'會導致更清潔設計在解耦方面。但不幸的是(可能是因爲遺留原因)類Thread不是最終的,因爲它可能應該是。實際上,根本不應該使用原始線程(除了學習Java線程編程的基礎知識外); Java新的併發框架爲多線程編程提供了更好(更安全)的抽象。 –

0

變化:

​​

本應打印「貓」

1

在線程t,重寫的被傳遞給它運行的run方法。我認爲這就是爲什麼當你調用一個具有可運行的線程的開始並且它的運行方法未被調用時!

0

創建線程對象時,例如t您已覆蓋run()方法。所以調用t.start()將執行重寫的方法。所以輸出Dog而不是Cat

0

將其更改爲:

new Thread(new Runnable() { 
    public void run() { 
     System.out.print("Cat"); 
    } 
}).start(); 

Runnable接口提供了一種替代的方法來利用Thread類,針對案件中,它不可能讓你的類擴展了Thread類。發生這種情況時,我們的類,我們想要在一個單獨的線程上運行應擴展一些其他類。由於沒有多重繼承,我們的類不能同時擴展Thread類和其他類。在這種情況下,你的類必須實現Runnable接口。

1

在第一個「新」語句中,創建一個Runnable實例,稍後傳入第二個「新」語句創建的線程中。輸出是狗,就像你在創建線程的第二個「新」語句中一樣,你也重寫了run()方法,這必須優先於你傳入的Runnable內部run()的實現。 這意味着Run()打印Cat的Runnable實現從不使用,只有run()實現打印Dog被Thread調用。

0

由於Runnable是一個接口,Thread是一個類,所以JVM管理它們的方式有些不同。

- 如果您實現了Runnable接口,則將在線程之間共享一個唯一的對象。

- 擴展Thread類,每個線程都會創建一個對象。

在某些情況下,runnable將佔用比Thread更少的內存。 此外,我認爲如果你擴展一個類,這是因爲你想重寫一些方法,所以從我的角度來看,如果你不會修改Thread類的任何方法或行爲,你應該使用Runnable ..

希望它有幫助。

相關問題