在程序开发中只要是多线程肯定永远以实现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方法中断线程。