问题:
我们知道start()方法的作用是: 1.启动线程 2.调用当前线程的run()
调用当前的run()方法 按道理应该是调用的是Thread类的run()方法
因为当前的线程是Thread 按正常应该调用的是自己的run()方法
为什么会调用到EvenNumberPrint()方法里面呢
如果用第一种方式创建 继承Thread类 我们把继承Thread类的run()方法给重写了 执行的就是重写的run()方法
然我们如果用第二种方式创建 并没有重写Thread类的run()方法 而是重写是Runnable类的run()方法
我们去看源码 去看Thread类的run()方法的源码
传进来一个Runnble实现类的对象 这个对象就把target给赋值了
解释原因
好的,让我们来看一下 `Thread` 类的源码,特别是 `run()` 方法的实现,以及它是如何与 `Runnable` 接口交互的。
```java
public class Thread implements Runnable {
/* 省略其他部分 */private Runnable target;
/* 省略其他部分 */
@Override
public void run() {
if (target != null) {
target.run();
}
}/* 省略其他部分 */
}
```在 `Thread` 类中,有一个 `target` 成员变量,用来持有一个 `Runnable` 对象。当 `Thread` 的 `run()` 方法被调用时,它会检查 `target` 是否为 `null`,如果不为 `null`,则调用 `target` 的 `run()` 方法。
那么当你创建一个 `Thread` 对象时,并传入一个实现了 `Runnable` 接口的对象作为参数,实际上是将这个 `Runnable` 对象赋值给了 `Thread` 的 `target` 成员变量。
举个例子,假设有如下代码:
```java
Runnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
```在这个例子中,当你调用 `thread.start()` 时,`Thread` 类内部会调用 `run()` 方法。而在 `run()` 方法内部,它会检查 `target` 是否为 `null`,然后调用 `target.run()` 方法。由于 `target` 已经被设置为 `MyRunnable` 对象,所以实际上会调用 `MyRunnable` 类中的 `run()` 方法。
因此,从源码的角度来看,即使你是通过 `Thread` 类来启动线程,并调用 `run()` 方法,但由于 `target` 成员变量的存在,实际上会调用 `Runnable` 接口中的 `run()` 方法,这就是为什么即使在多线程中,调用 `run()` 方法也会执行 `Runnable` 对象的 `run()` 方法。
当你创建一个 `Thread` 对象并传入一个实现了 `Runnable` 接口的对象时,实际上是将这个 `Runnable` 对象存储在 `Thread` 内部。这个 `Runnable` 对象实现了 `run()` 方法。当你调用 `start()` 方法启动线程时,`Thread` 类会调用 `run()` 方法。但是在 `Thread` 类中,它不直接调用自己的 `run()` 方法,而是检查内部存储的 `Runnable` 对象是否为空,如果不为空,就调用这个 `Runnable` 对象的 `run()` 方法。
所以,即使你在 `Thread` 对象上调用了 `run()` 方法,它实际上会调用存储在 `Thread` 内部的 `Runnable` 对象的 `run()` 方法。这就是为什么在多线程环境中调用 `run()` 方法会执行 `Runnable` 对象的 `run()` 方法。