在程序開發中只要是多線程肯定永遠以實現Runnable接口爲主,因爲實現Runnable接口相比繼承Thread類有如下好處:
- 避免點繼承的侷限,一個類可以繼承多個接口。
- 適合於資源的共享
因爲Java本來就是面向接口的,所以第一個特性應該很容易理解,下面我們以買票爲例,通過Thread類完成要賣出30張票。雖然現在程序中有三個線程,但是一共賣了10張票,也就是說使用Runnable實現多線程可以達到資源共享目的。
用繼承Thread實現
MyThread.java
package testthreadandrunnable;
class MyThread extends Thread {
private int ticket = 10;
private String name;
public MyThread(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 500; i++) {
if (this.ticket > 0) {
System.out.println(this.name + "賣票---->" + (this.ticket--));
}
}
}
}
Application.java
package testthreadandrunnable;
public class Application {
public static void main(String[] args) {
//繼承Thread來實現多線程
MyThread mt1= new MyThread("一號窗口");
MyThread mt2= new MyThread("二號窗口");
MyThread mt3= new MyThread("三號窗口");
mt1.start();
mt2.start();
mt3.start();
//實現Runnable接口實現多線程
/*MyThreadForRunnable mt = new MyThreadForRunnable();
Thread t1 = new Thread(mt,"一號窗口");
Thread t2 = new Thread(mt,"二號窗口");
Thread t3 = new Thread(mt,"三號窗口");
t1.start();
t2.start();
t3.start(); */
}
}
實現Runnable接口
MyThreadForRunnable.java
package testthreadandrunnable;
public class MyThreadForRunnable implements Runnable {
private int ticket = 10;
private boolean flag = true;
public void run() {
while (flag) {
if (this.ticket > 0) {
System.out.println(Thread.currentThread().getName() + "賣票---->"
+ (this.ticket--));
} else {
flag = false;
}
}
}
}
Application.java
package testthreadandrunnable;
public class Application {
public static void main(String[] args) {
//繼承Thread來實現多線程
/*MyThread mt1= new MyThread("一號窗口");
MyThread mt2= new MyThread("二號窗口");
MyThread mt3= new MyThread("三號窗口");
mt1.start();
mt2.start();
mt3.start();*/
//實現Runnable接口實現多線程
MyThreadForRunnable mt = new MyThreadForRunnable();
Thread t1 = new Thread(mt,"一號窗口");
Thread t2 = new Thread(mt,"二號窗口");
Thread t3 = new Thread(mt,"三號窗口");
t1.start();
t2.start();
t3.start();
}
}
很容易發現問題,如果用Runnable可以很容易實現數據共享。
注意一點,結束線程
其實細心一點分析一下,就能看到,兩個run裏面的我故意用了不同的方式結束線程,其實第一種for循環不是特別好,500,那剩下的都浪費了,但是第二種設置一個flag的方式就不會出現浪費。
有三種方法可以使終止線程。
使用退出標誌,使線程正常退出,也就是當run方法完成後線程終止。
使用stop方法強行終止線程(這個方法不推薦使用,因爲stop和suspend、resume一樣,也可能發生不可預料的結果)。
- 使用interrupt方法中斷線程。