java中可有兩種方式實現多線程:
一種是繼承Thread類;
一種是實現Runnable接口;
Thread類
是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的run()方法就可以實現多線程操作了,但限制是一個類只能繼承一個父類
package org.thread.demo;
class MyThread extends Thread{
private String name;
public MyThread(String name) {
super();
this.name = name;
}
public void run(){
for(int i=0;i<10;i++){
System.out.println("線程開始:"+this.name+",i="+i);
}
}
}
package org.thread.demo;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("線程a");
MyThread mt2=new MyThread("線程b");
mt1.run();
mt2.run();
}
}
但這種調用是順序執行的,先執行mt1,然後mt2。沒有並行。並行需要調用start()方法,則會通過JVM找到run()方法,在jdk中可以看源碼
package org.thread.demo;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("線程a");
MyThread mt2=new MyThread("線程b");
mt1.start();
mt2.start();
}
};
start()—用於啓動線程。
使用了private native void start();其中native關鍵字表示可以調用操作系統的底層函數,那麼這樣的技術成爲JNI技術(java Native Interface)
但實際開發多線程操作很少用Thread類,而是通過Runnable接口完成。
public interface Runnable{
public void run();
}
例子:
package org.runnable.demo;
class MyThread implements Runnable{
private String name;
public MyThread(String name) {
this.name = name;
}
public void run(){
for(int i=0;i<100;i++){
System.out.println("線程開始:"+this.name+",i="+i);
}
}
};
上例或者直接,實例化藉口,重載run函數:
package org.runnable.demo;
import org.runnable.demo.MyThread;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("線程a");
MyThread mt2=new MyThread("線程b");
new Thread(mt1).start();
new Thread(mt2).start();
}
}
Runnable run = new Runnable() {
@Override
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println(i);
}
}
};
調用通過
Thread thread = new Thread(run);
thread.start();
用Runnable定義的子類中沒有start()方法。所以需要通過Thread類來啓動Runnable實現的多線程,也就是說用start()才能協調系統的資源,
Thread構造方法:public Thread(Runnable targer)。
Runnable接口相比繼承Thread類有如下好處:
避免點繼承的侷限,一個類可以繼承多個接口。
適合於資源的共享
而繼承Thread不能直接進行多線程工作,你得爲你的每一部分工作都定義一個線程。
比如買票實例,使用Thread就沒有辦法實現多線程共享票務資源,每個Thread類擁有自己獨立的佔據資源。使用Runnable可以共享資源,一起共享總票務資源,如:
class MyThread implements Runnable{
private int ticket=10;
public void run(){
for(int i=0;i<20;i++){
if(this.ticket>0)
System.out.println("賣票:ticket"+this.ticket--);
}
}
};
MyThread mt=new MyThread();
new Thread(mt).start();//同一個mt,但是在Thread中就不可以,如果用同一
new Thread(mt).start();//個實例化對象mt,就會出現異常
new Thread(mt).start();