两者都可以实现多线程,那么两者的区别和联系有哪些?
Thread类的定义。
public class Thread extends Object implements Runnable
从Thread类的定义可以清楚的发现,Thread类也是Runnable接口的子类,但是Thread类中并没有完全地实现Runnable接口中的run()方法,
区别:如果一个类继承Thread类,则不适合于多个线程共享资源,而实现了Runnable接口,就可以方便地实现资源的共享。
范例:继承Thread不能共享资源
package ThreadDemo01;class MyThread2 extends Thread {private int ticket = 5;public void run() { // 覆写Thread类的run()方法for (int i = 0; i < 100; i++) {if (ticket > 0) {System.out.println("买票:tick=" + ticket--);}}}
}public class ThreadDemo04 {public static void main(String[] args) {MyThread2 mt1 = new MyThread2();// 创建线程对象1MyThread2 mt2 = new MyThread2();// 创建线程对象2MyThread2 mt3 = new MyThread2();// 创建线程对象3mt1.start();// 启动线程1mt2.start();// 启动线程2mt3.start();// 启动线程3}
}
结果:
买票:tick=5
买票:tick=4
买票:tick=3
买票:tick=2
买票:tick=1
买票:tick=5
买票:tick=4
买票:tick=3
买票:tick=2
买票:tick=1
买票:tick=5
买票:tick=4
买票:tick=3
买票:tick=2
买票:tick=1
范例:Runnable可以实现资源共享
package test1;class MyThread implements Runnable {private int ticket = 5;public void run() {for (int i = 0; i < 100; i++) {if (ticket > 0) {System.out.println("买票:ticket=" + ticket--);}}}
}public class ThreadDemo02 {public static void main(String[] args) {MyThread mt1 = new MyThread(); // 创建线程对象new Thread(mt1).start();new Thread(mt1).start();new Thread(mt1).start();new Thread(mt1).start();new Thread(mt1).start();new Thread(mt1).start();new Thread(mt1).start(); // 启动了7个线程}
}
结果:
买票:ticket=5
买票:ticket=4
买票:ticket=3
买票:ticket=2
买票:ticket=1
虽然启动了7个线程,但是指卖出了五张票
使用Runnable的好处是:
1.适合多个相同程序代码的线程去处理同一资源的情况
2.可以避免由与java的单继承特性带来的局限性
3.增强了程序的健壮性,代码能够被多线程共享代码与数据独立