Runnable接口
线程可以驱动任务,因此我们需要一种描述任务的方式,这可以由Runnable接口来提供。要想定义任务,只需实现Runnable接口并编写run()方法,使得该任务可以执行你的命令。当从Runnable导出一个类时,它必须具有run方法,但是这个方法没有特殊之处--它不会产生任何内在的线程能力。要实现线程能力,你必须显式地将一个任务附着到线程上。
class Launch implements Runnable {
int countDown = 10;
static int taskCount = 0;
private final int id = taskCount++;
public String count() {
return "#" + id + "(" + countDown + ")";
}
@Override
public void run() {
while (countDown-- > 0) {
System.out.println(count());
Thread.yield();//1
}
}
}
public class ThreadTest {
public static void main(String[] args) {
Launch l = new Launch();
l.run();
}
}
//1
//对线程调度器(Java线程机制的一部分,可以将CPU从一个线程转移给另一个线程)的一种建议。
//它在声明,我已经执行完生命周期中最重要的部分了,此刻正是切换给其他任务执行一段时间
//的大好时机。
/*输出
#0(9)
#0(8)
#0(7)
#0(6)
#0(5)
#0(4)
#0(3)
#0(2)
#0(1)
#0(0)
*/
从Runnable导出一个类,必须有run方法,但这个方法并没有特殊之处--它不会产生任何内在的线程能力。要实现线程行为,必须显式地将一个任务附着到线程上。
将Runnable对象转化为工作任务的传统方式是把它提交给一个Thread构造器。调用Thread对象的start方法为该线程执行必要的初始化操作,然后调用Runnable的run方法,以便在这个新线程中启动该任务。尽管start方法看起来是产生了一个对长期运行方法的调用,但是从输出中可以看到,start迅速的返回了
public class ThreadTest {
public static void main(String[] args) {
Thread t = new Thread(new Launch());
t.start();
System.out.println("Waiting...");
}
}
/*输出
Waiting...
#0(9)
#0(8)
#0(7)
#0(6)
#0(5)
#0(4)
#0(3)
#0(2)
#0(1)
#0(0)
*/
因为Waiting消息在倒计时完成前就出现了。实际上,你产生的是Launch.run方法的调用,并且这个方法还没用完成,但因为Launch.run方法是由不同线程执行的,因此你仍旧可以执行main线程中的其他操作。