15.2.3 使用Runnable接口
我们知道,Java中的类只能够是单继承,也就是说,如果一个类为了使用线程而继承了Thread类,它就不能再继承别的类了。这很可能给编程带来不便。本节中介绍的就是一种脱离继承来使用线程的方法。这个方法的核心就是Runnable接口。
Runnable接口的全限定名是java.lang.Runnable。它其中只有一个抽象方法void run()。为了了解如何在线程中使用Runnable接口,我们还需要看一下Thread类中的一个叫做target的属性和Thread类中的run()方法。Thread类中有一个类型为Runnable的属性,叫做target。而Thread类的run()方法用到了这个属性,run()方法的代码如下:
publicvoidrun() {// Thread类的run()方法
if(target !=null) {// 检查target属性是否为空,target属性是Runnable
// 类型的引用
target.run();// 如果不为空则执行run()方法
}// 否则什么都不做
}// run()方法结束
如何让target的值不为null呢?Thread类的另一个构造方法就是用来给target属性赋值的,这个构造方法是Thread(Runnable)。当调用这个构造方法时,传递过来的参数就会赋值给target属性。也就是说,如果直接使用Thread类也是可以的,步骤如下:
(1)实现Runnable接口,例如叫做MyRunnable,并在MyRunnable类的run()方法里编写想要让线程做的事情。
(2)创建一个MyRunnable的实例。
(3)通过构造方法Thread(Runnable)来创建Thread类的实例。
这时再调用start()方法启动这个线程,执行的就是MyRunnable中run()方法的代码了。下面我们来使用以下这种方法,首先是MyRunnable类。
packagecom.javaeasy.usethread;// 程序在的包
publicclassMyRunnableimplementsRunnable {// 实现Runnable接口
publicvoidrun() {// 实现run()方法
System.out.println("这是在另一个线程中执行的代码。");
// 向控制台输出一行字
}// run()方法结束
}
MyRunnable实现了Runnable接口,其run()方法就是线程会去执行的方法。然后是例程。
packagecom.javaeasy.usethread;
publicclassUseMyRunnable {
publicstaticvoidmain(String[] args) {// 例程的main()方法
// 创建一个MyRunnable类的实例,MyRunnable,MyRunnable实现了Runnable
// 接口
MyRunnable runnable =newMyRunnable();
Thread thread =newThread(runnable);// 调用Thread相应的构造
// 方法,传入参数
thread.start();// 启动线程
}
}
在例程中,按照步骤分别创建MyRunnable类的实例,调用Thread相应的构造方法,最后启动线程。因为Runnable是个接口,为了简单一些,还可以使用前面学到过的匿名类来实现相同的功能。使用匿名类的例程如下:
package com.javaeasy.usethread;
public class UseRunnable {
public static void main(String[] args) { // 测试类的main()方法
// 创建一个线程,参数为一个实现了Runnable接口的匿名类的实例
Threadthread=newThread(new Runnable() {