Java 多线程继承Thread类方式和实现Runnable接口方式的联系与区别
这里先不考虑同步的问题
1.通过模拟三个售票窗口售票来区别两种方法的异同点
1.1.Thread类方式和实现Runnable接口方式的联系
- 无论哪个,都是实现Runnable接口,Thread类其实一开始的时候就是实现了Runnable接口,所以只要是实现多线程都离不开Runnable接口。
- jdk的Thread类源码中,run()方法中,其实也对构造器有没有入参实现Runnable接口的对象进行判断,然后根据结果执行相对应的方法。下面有对应的Thread类的对Runnable接口的参数,构造器和run()最终执行的是哪个地方的代码Tread里还是实现Runnable接口里的。
1.2.Thread类方式和实现Runnable接口方式的区别
- 继承Thread : 线程代码存放Thread子类run方法中。
- 实现Runnable:线程代码存在接口的子类的run方法。
- 实现过程步骤不一样,一个需要构造器入参一个实现Runnable接口的对象
1.3.Thread类方式和实现Runnable接口方式哪个比较好?
- 避免了单继承的局限性
- 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源下面Demo主要是就是说明这个问题
- 一般在项目情况中,都时优先使用实现接口的方式。
2.继承Thread类方式
/*
* 模拟火车站售票窗口,开启三个窗口售票,总票数为100张
*/
class Window extends Thread{
static int ticket = 100;//得写成静态的
public void run() {
while(true) {
if(ticket > 0) {
System.out.println(Thread.currentThread().getName()+"售票,票号为:"+ticket--);
}else {
break;
}
}
}
}
public class TestWindow {
public static void main(String[] args) {
Window w1 = new Window();
Window w2 = new Window();
Window w3 = new Window();
w1.setName("窗口一");
w2.setName("窗口二");
w3.setName("窗口三");
w1.start();
w2.start();
w3.start();
}
}
3.使用实现Runnable接口方式:多窗口售票
//使用实现Runnable接口方式:售票
class Window implements Runnable{
int ticket = 100;
public void run() {
while(true) {
if(ticket > 0) {
System.out.println(Thread.currentThread().getName()+"售票,票号为:"+ticket--);
}else {
break;
}
}
}
}
public class TestWindow {
public static void main(String[] args) {
Window w = new Window();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口1");
t3.setName("窗口1");
t1.start();
t2.start();
t3.start();
}
}