定义任务
要想定义一个任务,只需要实现Runnable接口并编写run()方法
例程:
//: concurrency/LiftOff.java
// Demonstration of the Runnable interface.
public class LiftOff implements Runnable {
protected int countDown = 10; // Default
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {}
public LiftOff(int countDown) {
this.countDown = countDown;
}
public String status() {
return "#" + id + "(" +
(countDown > 0 ? countDown : "Liftoff!") + "), ";
}
public void run() {
while(countDown-- > 0) {
System.out.print(status());
Thread.yield();
}
}
} ///:~
Thread.yield() 的调用时对线程调度器的一种建议,它在声明:”我已经执行完生命周期中最重要的部分了,此刻正是切换给其他任务执行一段时间的大好时机“
//: concurrency/MainThread.java
public class MainThread {
public static void main(String[] args) {
LiftOff launch = new LiftOff();
launch.run();
}
} /* Output:
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!),
*///:~
当从Runable导出一个类时,它必须具有run()方法,但是这个方法并无特殊之处–它不会产生任何内在的线程能力,要实现线程行为,你必须显示的调用一个任务附着到线程上
Thread类
Thread构造器只需要一个Runable对象,调用Thread对象的start()方法为该线程执行必须的初始化操作。
例程:
//: concurrency/BasicThreads.java
// The most basic use of the Thread class.
public class BasicThreads {
public static void main(String[] args) {
Thread t = new Thread(new LiftOff());
t.start();
System.out.println("Waiting for LiftOff");
}
} /* Output: (90% match)
Waiting for LiftOff
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!),
*///:~
注意:main()和LiftOff.run()是程序中与其他线程“同时”执行的代码。
使用Thread与使用普通实现Runable接口对象的区别?
在使用普通对象时,这对于垃圾回收来说是一场公平的游戏,但是使用Thread时,情况就不同了,每个Thread都“注册”了它自己,因此确实有一个对它的引用。而且在它的任务退出其run()并死亡之前,垃圾回收期无法清除它。因此,一个线程会创建一个单独的执行线程,在对start()的调用完成之后。它仍然会继续存在