Java語言的一個重要功能特點就是內置對多線程的支持,它使得編程人員可以很方便地開發出具有多線程功能,能同時處理多個任務的功能強大的應用程序。
Thread類及Runnable接口
可以將一個線程理解成以下三個部分的組合。
(1)CPU:虛擬的CPU,專門用於執行該線程的任務。
(2)Code:代碼,即線程中要執行的指令,在程序中表現爲特定的方法。
(3)Data:數據,即線程中要處理的數據,在程序中表現爲變量。
在Java中,有java.lang.Thread類來實現線程的概念,其中:
虛擬的CPU,由java.lang.Thread類封裝和虛擬;CPU所執行的代碼,在構造Thread類時,傳遞給Thread類對象。CPU所處理的數據,在構造Thread類時,傳遞給Thread類對象。
爲了構造一個Thread類,可以向Thread的構造函數傳遞一個Runnable對象,這個對象就是線程所需要的代碼和數據的封裝。
Runnable對象是指實現了java.lang.Runnable接口的任何對象,Runnable接口只有一個方法:
public void run();
這個run()方法實際上就是線程所要執行的代碼。
要啓動線程中的代碼,只需要執行Thread類的start()方法,則系統會在可能的情況下去執行run()方法中所規定的代碼。
創建線程對象的兩種方法
創建線程對象,要傳遞代碼與數據,而傳遞代碼與數據有兩種方法,一是通過繼承Thread類,一是向Thread類傳遞一個Runnable對象。
1.通過繼承Thread類創建線程
從Thread派生一個新類,在其中加入屬性及方法,同時覆蓋run()方法。當創建這樣一個派生類的新對象後,使用start()方法,即可啓動該線程。
例1 TestThread1.java簡單的線程
public class TestThread1 {
public static void main(String[] args) {
Thread t = new MyThread();
t.start();
}
}
class MyThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print(" " + i);
}
}
}
在程序中通過繼承,定義了MyThread類。用new創建了一個線程實例,用start()方法進行啓動,程序結果如下圖所示。
2.通過向Thread()構造方法傳遞Runnable對象來創建線程
通過向Thread()構造方法傳遞Runnable對象來創建線程,是第二種方法。
例2 TestThread2.java實現Runnable
public class TestThread2 {
public static void main(String[] args) {
MyTask mytask = new MyTask(100);
Thread thread = new Thread(mytask);
thread.start();
}
}
class MyTask implements Runnable {
private int n;
public MyTask(int n) {
this.n = n;
}
public void run() {
for (int i = 0; i < n; i++) {
System.out.print(" " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {}
}
}
}
運行結果如下圖所示。
該程序定義了一個類MyTask,它實現了Runnable接口,也就是說,它含有public void run()方法。在創建線程時,先創建一個MyTask對象,再將此對象作爲Thread構造方法的參數。
3.兩種方法的比較
直接繼承Thread類,這種方法的特點是:編寫簡單,可以直接操作線程;但缺點也是明顯的,因爲若繼承Thread類,就不能在從其他類繼承。
使用Runnable接口,這種方法的特點是:可以將Thread類與所要處理的任務的類分開,形成清晰的模型;還可以從其他類繼承。