Java多线程中Thread与Runnable的区别
定义
extends Thread
-
子类继承Thread具备多线程能力,可以实现多线程;
-
启动线程的方法:①创建子类对象 ②对象名.start();
-
不建议使用:避免多线程OOP单继承的局限性(OOP:Object Oriented Programming,面向对象的编程、类似的还有OOD(面向对象的设计),OOA(面向对象的分析));
implements Runnable
-
实现Runnable接口具有多线程能力,可以实现多线程
-
-
推荐使用:避免OOP单继承的局限性,方便被同一个对象多次使用;
实际上所有的多线程代码都是通过执行Thread的start()方法来运行的。所以不管是继承Thread类还是实现Runnable接口来实现多线程,最终都是通过Thread对象的API来控制线程的,因此熟悉Thread类的API是进行多线程编程的基础。(
示例
继承Thread实现多线程1
package 多线程1;
public class TestThread1 extends Thread {
上述示例执行后可以看到:主线程和子线程的执行顺序本该是“先执行子线程、再执行主线程”,事实上却是主线程和子线程交替执行(无法人为控制,由CPU调度执行),这便是多线程的特征;
继承Thread实现多线程2——下载网络图片
package 多线程1;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
//练习网络下载图片
public class TestThread2 extends Thread {
private String url;
private String name;
public TestThread2(String url,String name){
this.name=name;
this.url=url;
}
注:代码中图片为网络上随机寻找
由以上代码也可以看出:下载的三张图片的顺序本应该是"p1-->p2-->p3",事实上执行后发现三张图片的下载顺序是随机的(受CPU自由调度)。
Runnable接口实现多线程1
package 多线程1;
public class TestThread4_Runnable implements Runnable {
上述代码的执行结果也是随机的,无法根据代码的编写顺序来判断执行顺序。
Runnable接口实现多线程2——龟兔赛跑
package 多线程1;
public class Race implements Runnable {
private String winner=null;
上述代码模拟了龟兔赛跑,乌龟和兔子“随机跑步”,兔子在中途“频繁”休息,执行结果最终是乌龟成为了winner!
Thread.sleep()方法调用的目的是不让当前线程独自霸占CPU,以留出一定时间给其他线程执行的机会。 实际上所有的多线程代码执行顺序都是不确定的,每次执行的结果都是随机的。