线程可以驱动任务,因此你需要一种描述任务的方式,这可以由Runnable接口来提供。要想定义任务只需实现Runnable接口并编写run()方法,使得该任务可以执行你的命令。
/** * Created by DELL_USER on 2018/4/12. */ public class LiftOff implements Runnable { protected int countDown=10; private static int taskCount=0; private static final int id=taskCount++; public LiftOff() { } public LiftOff(int countDown) { this.countDown = countDown; } public String status(){ return "#"+id+"("+(countDown>0 ? countDown : "Listoff")+")"; } @Override public void run() { while (countDown-- >0){ System.out.print(status()); Thread.yield(); } } }
在run()中对静态方法,Thread.yield()的调用是对线程调度调度器(java线程机制的一部分,可以将CPU从一个线程转移给另一个线程)的一种建议,它在声明:“我已经执行完生命周期中最重要的部分了,此刻正是切换给其他任务执行一段时间的大好时机。”当从Runnable导出一个类时,它必须具有run()方法,但是这个方法并无特殊之处--它不会产生任何内在的线程能力。要实现线程行为,你必须显示的将一个任务附着到线程上。
Thread类
将Runnable对象转变为工作任务的传统方式是把它提交给一个Thread构造器,下面的示例展示了如何使用Thread来驱动LiftOff对象:
public class BasicThreads { public static void main(String[] args){ Thread t=new Thread(new LiftOff()); t.start(); System.out.print("Waiting for LiftOff"); } }
Thread构造器只需要一个Runnable对象。调用Thread对象的start()方法为该线程执行必需的初始化操作,然后调用Runnable的run()方法,以便在这个新线程中启动该任务。
你可以很容易的添加更多的线程去驱动更多的任务。
public class MoreBasicThread { public static void main(String[] args){ for(int i=0;i<5;i++){ new Thread(new LiftOff()).start(); System.out.print("Waiting for LiftOff"); } } }
上面程序输出说明不同任务的执行线程被换进换出时混在了一起。这种交换是由线程调度器自动控制的。如果在你的机器上有多个处理器,线程调度器将会在这些处理器之间默默的分发线程。这个程序一次运行结果可能与另一次运行结果不同,因为线程调度机制是非确定性的。
当main()创建Thread对象时,它并没有捕获任何对这些对象的引用。在使用普通对象时,这对于垃圾回收来说是一场公平游戏,但是在使用Thread时,情况就不同了。每个Thread都注册了它自己,因此确实有一个对它的引用,而且在它的任务退出其run(),并死亡之前,垃圾回收器无法清除它。