首页 > runnable是如何避免java单继承带来的局限性的?

runnable是如何避免java单继承带来的局限性的?


runnable是接口

可以实现多个接口


单继承的意思是,一个子类不能有两个以上父类
具体解释:
若有一个A类,一个B类,且A,B类独立(没有共同父类,也相互不为父类)。
新建一个类C,想要同时继承A,B类,在JAVA中无法直接实现。
要实现,只能复制A类的内容,再继承B类,或者反过来,这将会很麻烦,而且代码会很丑陋。

局限性由上面可以得到:想要得到两个类的特性是不能通过继承实现。

而接口出现可以解决这个问题。
因为,一个类可以实现多个接口

最后解释一下Runnable是如何避免java单继承带来的局限性的。
如果你想写一个类C,但这个类C已经继承了一个类A,此时,你又想让C实现多线程。用继承Thread类的方式不行了。(因为单继承的局限性)
此时,只能用Runnable接口。
Runnable接口就是为了解决这种情境出现的。


@RK3258 其实还是介绍的接口实现类继承的区别,我从另外一个层面来回答这个问题。

首先 ThreadRunnable 实际上是一种静态代理的实现方式。我们可以简单看一下源代码就了解了:

public interface Runnable {
    public abstract void run();
}

public class Thread implements Runnable {
    ...
    private Runnable target;
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
    public void run() {
        if (target != null) {
            target.run(); //代理的target的run方法
        }
    }
}

另外一个我们知道线程启动是调用 thread.start() 方法,但是 start() 方法会调用 nativestart0()方法,继而由 JVM 来实现多线程的控制,因为需要系统调用来控制时间分片。

现在我们可以深入理解一下两种线程实现方式的异同。

Class MyThread extends Thread(){
    public int count = 10;
    public synchronized void run(){
        while(count>0){
            count--;
        }
    } 
}

new Mythread().start(); //启动 n 个线程
new Mythread().start();

这种实现方式实际上是重写了 run() 方法,由于线程的资源和 Thread 实例捆绑在一起,所以不同的线程的资源不会进行共享。

Class MyThread implements Runnable{
    public int count = 10;
    public synchronized void run(){
        while(count>0){
            count--;
        }
    } 
}
MyThread mt = new MyThread();
new Thread(mt).start();  //启动 n 个线程
new Thread(mt).start();

这种实现方式就是静态代理的方式,线程资源与 Runable 实例捆绑在一起Thread 只是作为一个代理类,所以资源可以进行共享。

当然 @RK3258 说的接口与类的区别我就不赘述了。

另外从 Java 语言设计者的角度来说,Runnable 可以理解为 Task,对应的是具体的要运行的任务,而 Thread 对应某一个具体的线程运行的载体。综上,继承 Thread 来实现,可以说是不推荐的。

【热门文章】
【热门文章】