線程與進程很相似,他們都是程序的一個順序執行機構,但又有一些區別。進程是一個實體,每個進程都有自己獨立的狀態和自己的專用數據段。線程則共享數據,同一個程序中的所有線程只有一個數據段,線程間可能互相影響,比如數據訪問的互斥和同步。
線程本身的數據通常只有寄存器數據和程序執行時的堆棧段,所以線程的切換比進程的負擔要小。線程不能自動運行,必須躋身在某一進程中,由進程觸發。一個進程可以有多個線程且進程間不共用線程。
實現多線程有兩種方法,一是繼承Thread類,二是實現Runnable接口。
繼承Thread類創建線程時,首先要定義一個Thread類的子類,并在該子類中重寫run()方法。run()方法是線程體,說明該線程的具體操作。需要創建線程時,只需創建該子類的對象在調用其start()方法即可。
實現Runnable接口創建線程必須重寫該接口的run()方法(Runnable接口只有一個run()方法)。
由于Java是單繼承語言,不直接支持多繼承,如果一個類已經是其他類的子類,就不能在繼承Thread方法使該類成為線程類,這時就要采用實現Runnable接口的方式。
兩種方法創建的線程中具有相同目標對象的線程可以共享內存單元,但是實現Runnable接口的線程去創建目標對象的類可以是某個特定類的子類,因此實現Runnable接口創建線程比繼承Thread類創建線程更靈活。
舉幾個小例子來看一下哈
繼承Thread類實現的多線程:
class MyThread1 extends Thread{
private String name;
public MyThread1(String name){
this.name= name;
}
public void run(){
for(int i=0;i<15;i++){
System.out.println(this.name+"---->Is Running");
}
}
}
public class ThreadDemo01{
public static void main(String[] args){
Runnable r1 = new MyThread1("線程A");
Runnable r2 = new MyThread1("線程B");
Runnable r3 = new MyThread1("線程C");
Runnable r4 = new MyThread1("線程D");
Thread t1 = new Thread (r1);
Thread t2 = new Thread (r2);
Thread t3 = new Thread (r3);
Thread t4 = new Thread (r4);
t1.start();
t2.start();
t3.start();
t4.start();
//也可以這樣寫
/* MyThread mt1 = new MyThread("線程A");
MyThread mt2 = new MyThread("線程B");
MyThread mt3 = new MyThread("線程C");
MyThread mt4 = new MyThread("線程D");
mt1.start();
//同一線程不能連續啟動,編譯沒錯誤,但運行錯誤
mt2.start();
mt3.start();
mt4.start();*/
}
}
0.0!!運行結果好長,就不截圖了哈,可以自己試試。
實現Runnable接口的多線程(實現了共享資源):
class MyThread2 implements Runnable{
//定義十張票
private int ticket=10;
public void run(){
for(int i=0;i<500;i++){
if(this.ticket>0){
System.out.println("賣票-------"+(this.ticket--));
}
}
}
}
public class ThreadDemo02 {
public static void main(String[] args){
MyThread2 mt =new MyThread2();
//共享同一資源
Thread mt1 = new Thread(mt);
Thread mt2 = new Thread(mt);
Thread mt3 = new Thread(mt);
mt1.start();
mt2.start();
mt3.start();
}
}
運行結果: