Java多线程编程核心技术(第3版)
上QQ阅读APP看书,第一时间看更新

1.2.6 使用Runnable接口实现多线程的优点

使用继承Thread类的方式来开发多线程应用程序在设计上是有局限的,因为Java是单继承,不支持多继承,所以为了改变这种限制,可以使用实现Runnable接口的方式来实现多线程。下面来使用Runnable接口必要性的演示代码。

创建测试用的项目moreExtends,首先看一下业务A类,代码如下:


package service;

public class AServer {
    public void a_save_method() {
        System.out.println("a中的保存数据方法被执行");
    }
}

再来看业务B类,代码如下:


package service;

public class BServer1 extends AServer,Thread
{

    public void b_save_method() {
        System.out.println("b中的保存数据方法被执行");
    }
}

BServer1.java类不支持在extends关键字后写多个类名,也就是Java并不支持多继承的写法,所以在代码“public class BServer1 extends AServer, Thread”处出现异常信息:


Syntax error on token "extends", delete this token

这时就有使用Runnable接口的必要性了,创建新的业务B类,代码如下:


package service;

public class BServer2 extends AServer implements Runnable {
    public void b_save_method() {
        System.out.println("b中保存数据的方法被执行");
    }

    @Override
    public void run() {
        b_save_method();
    }
}

程序不再出现异常,通过实现Runnable接口,可间接实现“多继承”的效果。

另外需要说明的是,Thread.java类也实现了Runnable接口,如图1-17所示。

图1-17 Thread类实现Runnable接口

这就意味着构造函数Thread(Runnable target)不仅可以传入Runnable接口的对象,还可以传入一个Thread类的对象,这样做完全可以将一个Thread对象中的run()方法交由其他线程进行调用,示例代码如下:


public class Test {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        // MyThread是Thread的子类
        // 而Thread是Runnable的实现类
        // 所以MyThread也相当于是Runnable的实现类
        Thread t = new Thread(thread);
        t.start();
    }
}

在非多继承的情况下,使用继承Thread类和实现Runnable接口这两种方式在取得程序运行的结果上并没有太大的区别,但一旦出现“多继承”的情况,则建议采用实现Runnable接口的方式来处理多线程的问题。

另外,使用Runnable接口方式实现多线程可以把“线程”和“任务”分离,Thread代表线程,而Runnable代表可运行的任务,Runnable里面包含Thread线程要执行的代码,这样处理可以实现多个Thread共用一个Runnable。