1、通過實現Runnable介面線程建立
(1).定義一個類實現Runnable介面,重寫介面中的run()方法。在run()方法中加入具體的任務代碼或處理邏輯。
(2).建立Runnable介面實作類別的對象。
(3).建立一個Thread類的對象,需要封裝前面Runnable介面實作類別的對象。(介面可以實現多繼承)
(4).調用Thread對象的start()方法,啟動線程
範例程式碼:
01.package demo.thread;
02.
03.public class TreadDemo1 implements Runnable {
04. private int countDown = 10;
05. @Override
06. // 在run方法中定義任務
07. public void run() {
08. while (countDown-- > 0) {
09. System.out.println("#" + Thread.currentThread().getName() + "("
10. + countDown + ")");
11. }
12. }
13.
14. public static void main(String[] args) {
15. // Runnable中run方法是一個空方法,並不會產生任何線程行為,必須顯式地將一個任務附著到線程上
16. TreadDemo1 tt=new TreadDemo1();
17. new Thread(tt).start();
18. new Thread(tt).start();
19. System.out.println("火箭發射前倒計時:");
20. }
21.}
22.
運行結果:
火箭發射前倒計時:
#Thread-1(8)
#Thread-1(7)
#Thread-1(6)
#Thread-1(5)
#Thread-1(4)
#Thread-1(3)
#Thread-1(2)
#Thread-1(1)
#Thread-1(0)
#Thread-0(9)
2、通過繼承Thread類建立線程
(1).首先定義一個類去繼承Thread父類,重寫父類中的run()方法。在run()方法中加入具體的任務代碼或處理邏輯。
(2).直接建立一個ThreadDemo2類的對象,也可以利用多態性,變數聲明為父類的類型。
(3).調用start方法,線程t啟動,隱含的調用run()方法。
範例程式碼:
view plaincopy to clipboardprint?
01.package demo.thread;
02.
03.public class ThreadDemo2 extends Thread {
04. private int countDown = 10;
05.
06. @Override
07. // 在run方法中定義任務
08. public void run() {
09. while (countDown-- > 0) {
10. System.out.println("#" + this.getName() + "(" + countDown + ")");
11. }
12. }
13.
14. public static void main(String[] args) {
15. new ThreadDemo2().start();
16. new ThreadDemo2().start();
17. // 由於start方法迅速返回,所以main線程可以執行其他的操作,此時有兩個獨立的線程在並發運行
18. System.out.println("火箭發射前倒計時:");
19. }
20.}
21.
package demo.thread;
public class ThreadDemo2 extends Thread {
private int countDown = 10;
@Override
// 在run方法中定義任務
public void run() {
while (countDown-- > 0) {
System.out.println("#" + this.getName() + "(" + countDown + ")");
}
}
public static void main(String[] args) {
new ThreadDemo2().start();
new ThreadDemo2().start();
// 由於start方法迅速返回,所以main線程可以執行其他的操作,此時有兩個獨立的線程在並發運行
System.out.println("火箭發射前倒計時:");
}
}
運行結果:
#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-0(0)
火箭發射前倒計時:
#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)
#Thread-1(0)
3、兩種方式的比較
首先分析兩種方式的輸出結果,同樣是建立了兩個線程,為什麼結果不一樣呢?
使用實現Runnable介面方式建立線程可以共用同一個目標對象(TreadDemo1 tt=new TreadDemo1();),實現了多個相同線程處理同一份資源。
然後再看一段來自JDK的解釋:
Runnable 介面應該由那些打算通過某一線程執行其執行個體的類來實現。類必須定義一個稱為run 的無參數方法。
設計該介面的目的是為希望在活動時執行代碼的對象提供一個公用協議。例如,Thread 類實現了Runnable。啟用的意思是說某個線程已啟動並且尚未停止。
此外,Runnable 為非 Thread 子類的類提供了一種啟用方式。通過執行個體化某個Thread 執行個體並將自身作為運行目標,就可以運行實現 Runnable 的類而無需建立 Thread 的子類。大多數情況下,如果只想重寫run() 方法,而不重寫其他 Thread 方法,那麼應使用 Runnable 介面。這很重要,因為除非程式員打算修改或增強類的基本行為,否則不應為該類建立子類。
採用繼承Thread類方式:
(1)優點:編寫簡單,如果需要訪問當前線程,無需使用Thread.currentThread()方法,直接使用this,即可獲得當前線程。
(2)缺點:因為線程類已經繼承了Thread類,所以不能再繼承其他的父類。
採用實現Runnable介面方式:
(1)優點:線程類只是實現了Runable介面,還可以繼承其他的類。在這種方式下,可以多個線程共用同一個目標對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU代碼和資料分開,形成清晰的模型,較好地體現了物件導向的思想。
(2)缺點:編程稍微複雜,如果需要訪問當前線程,必須使用Thread.currentThread()方法。
轉自:http://software.intel.com/zh-cn/blogs/2011/11/16/java-12/?cid=sw:prccsdn2063