文章目录
多线程的基本实现方式(持续更新)
1、继承Thread类
使用步骤如下:
- 创建一个自己需要的线程类MyThread,使其继承Thread类
- 在MyThread类中覆写Thread类的run方法(run方法定义的是多线程要执行的业务)
- 使用从Thread继承来的start()方法启动多线程
代码实例如下:
// 第一步:创建
class MyThread extends Thread {
private String title;
public MyThread(String title){
this.title = title;
}
// 第二步:覆写
@Override
public void run(){
.../*执行业务*/
}
}
public static void main(String[] args){
// 第三步:用start()启动
new MyThread("线程1").start();
new MyThread("线程2").start();
new MyThread("线程3").start();
缺点:
Java支持类的多层继承,不支持类的多重继承,所以存在单继承局限。
2、 实现Runnable接口
实现Runnable接口的代码示例如下:
代码实例如下:
// 第一步:创建
class MyThread implements Runnable {
private String title;
public MyThread(String title){
this.title = title;
}
// 第二步:覆写
@Override
public void run(){
.../*执行业务*/
}
}
实现Runnable接口和继承Thread类没有区别,区别在于主程序如何创建线程实例。
start()方法时由Thread类提供的,我们需要用start()启动线程,所以在创建实例时需要用Thread类对其进行封装。
public static void main(String[] args){
// 第三步:用start()启动
Thread threadA = new Thread(new MyThread("线程1"));
Thread threadB = new Thread(new MyThread("线程2"));
Thread threadC = new Thread(new MyThread("线程3"));
threadA.start();
threadB.start();
threadC.start();
优点:
Java虽不支持类的多重继承,但支持接口的“多重实现”,即一个实现类可以实现多个接口以完成更复合的功能,弥补了第一种方法的缺点。
小tips
Thread类与Runnable接口的关系
可以从源码中看到,Thread也是Runnable接口的实现类
所以,继承Thread并覆写run方法,实际上是在覆写Runnable接口的run方法
为什么要用start()方法启动,而不是直接调用run()方法
因为查看Thread源码可以发现,start()方法里还会调用一个叫start0()的方法
native关键字是指Java本地接口调用(Java Native Interface),即 使用Java调用本机操作系统的函数功能完成一些特殊操作,而这样的代码开发在Java中很少出现。
start0方法类似于抽象方法,没有方法体,而是交给JVM(匹配不同的操作系统)实现。
为什么实现了Runnable还是需要用Thread封装呢?
可以从源码看到,Runnable接口只提供run()方法。
Thread的构造方法可以以Runnable的实现类作为参数,所以可以用上文方法来实现Runnable的多线程。
最后整理一下逻辑
Java设计了Runnable接口,并用Thread类实现了这个接口。
在Thread类中定义了start()方法用来启动线程,所以可以写一个Thread的继承类并将其实例化,再用实例调用start()方法。
但由于Java存在单继承局限,而实现接口则允许“多重实现”,所以我们可以改用实现Runnable接口的方法创建线程(可以同时实现其他接口完成其他业务)。
又因为我们需要用到start()方法来启动线程,而start()方法只存在于Thread类中,于是我们注意到Thread类提供了一种以Runnable对象为参数的构造方法,所以我们只需写好Runnable的实现类,然后用Thread封装起来,便既可以启动多线程,又可以兼顾其他业务。