java线程类Thread和Runnable的疑问有大神知道吗?

看Thread类发现它实现了Runnable接口:public class Thread implements Runnable。
我看到Runnable接口类里除了一个抽象run()方法什么也没有,也就是说Thread类实现Runnable接口只是为了实现这个接口的run方法。在使用线程时候Thread类中的run()方法还要被重写,那实现Runnable还有什么用啊?感觉没必要啊

Java 因为只支持继承于一个类,所以,如果当前类继承了Thread类就无法再继承其它类了。就跟楼上说的,java class可以实现多个接口。在这种情况下,它可以实现Runable接口里面的run 方法进而有多线程的特性,同时,也可以extends其他类进而继承父类的方法。一举两得

图片说明
通过查看Thread类的源码可以知道,Thread类中有一个接收Runnable接口参数的构造方法,此时我们的普通类去实现Runnable接口,就可以将该类
作为参数传递给Thread构造方法,这也就是实现Runnable接口开启线程的步骤,继续查看源码,发现构造方法里面调用了init方法
图片说明
该方法将传递过去的Runnable参数赋值给了自己的target属性,而该属性在类的开头就定义了,此时继续查看run()方法
图片说明
可以知道此时调用start()方法就是Runnable.run()。
底层的东西多去了解,自然而然你就知道了

第一:Thread方法中的run方法是有实现的:
@Override
public void run() {
if (target != null) {
target.run();
}
}
而不是空的run方法

为什么实现Runnbale接口
如果Thread类没有实现Runnable接口的话,我们要创建一个线程是不是只有两种方法:

1.
Thread thread=new Thread(){
public void run(){代码}
};

这种方法的缺点:如果有多个地方要进行同样的逻辑处理,我们就得在多个地方写同样的代码,就会出现冗余,这不符合java中封装的概念。
如果实现了Runnable接口,我们只要创建一个Runnable对象,以后创建Thread只要使用这个Runnable对象就可以了,Thread a=new Thread(runnable接口);
在所有的地方只要使用上面一行代码,就会进行封装。

2.
你写一个Thread的子类,重写run方法。class myThread extends Thread{public void run(){}}
这个可以实现上面封装的问题,只要写一次逻辑run方法代码,然后多次创建myThread类。进行多线程执行

但是,这样我们就不能继承其他的类。
如果你已经继承一个类,就不能再次继承Thread类了。就不能使用这个类进行多线程执行代码。

如果Thread实现Runnable接口,我们可以在方法中参数类型为Runnable参数时候,传递一个Thread的对象,因为Thread是Runnable的一个实现。

实现Runnable接口和继承Thread类的最大区别在于多继承,假如我一个类是基于另外一个类的,这时候我这个类要实现多线程你怎么办?所以,很多时候,或者说绝大多数的情况下,我们都是实现Runnable接口,而不是继承Thread类,留着继承空间,可以更好扩展,简单来说,实现Runnable接口可以让代码可复用性提高,耦合性降低

建议去看看java 面向对象编程的10条原则,理解一下面向接口编程的好处

你这个问题有两种问法啊。
是Thread类实现Runnable接口有什么意义。
还是普通类实现Runnbale接口有什么意义。

Thread类实现Runnbale有什么意义的话。按照你上面这个问题,Thread类不实现Runnbale,使用线程的时候哪来的run()可以重写。。。
其实查一下Thread类的run()源码就知道了。
顺序是这样
private Runnable target;
Thread无参和有参构造函数中有一个的init()方法
init()有一段代码this.target=target
再看Thread中的run()
public void run(){
if(target!=null)
target.run();
}
这里面就是调用的刚刚实现Runnable接口的类中的run()。
我们平常直接继承Thread也能用run(),因为子类直接重写了Thread中run()方法。调用的也是子类的run()