控制台程序。
程序总是至少有一个线程,程序开始执行时就会创建这个线程。在普通的Java应用程序中,这个线程从mian()方法的开头启动。
要开始执行线程,可以调用Thread对象的start()方法。在新线程中执行的代码总是一个名为run()的方法,这是一个公共方法,不带参数,也没有返回值。程序中除了主线程之外的其他线程总是在表示线程的对象的run()方法中启动。
如果希望用于表示程序中线程的类执行某些操作,就必须为类实现run()方法,因为从Thread类继承的run()方法什么也不做。
重点:程序没有调用run()方法来启动线程,而是调用表示线程对象额start()方法,进而调用run()方法。
可以用以下两种方法来定义表示线程的类:
1、定义Thread的子类,提供run()方法的定义以重写继承而来的方法。
2、把自己的类定义为实现了Runnable()接口,这个接口声明了run()方法,之后再在需要时在自己的类中创建Thread对象。
下面为使用第一种方法:
import java.io.IOException; public class TryThread extends Thread {
public TryThread(String firstName, String secondName, long delay) {
this.firstName = firstName; // Store the first name
this.secondName = secondName; // Store the second name
aWhile = delay; // Store the delay
setDaemon(true); // Thread is daemon
} public static void main(String[] args) {
// Create three threads
Thread first = new TryThread("Hopalong ", "Cassidy ", 200L);
Thread second = new TryThread("Marilyn ", "Monroe ", 300L);
Thread third = new TryThread("Slim ", "Pickens ", 500L); System.out.println("Press Enter when you have had enough...\n");
first.start(); // Start the first thread
second.start(); // Start the second thread
third.start(); // Start the third thread try {
System.in.read(); // Wait until Enter key pressed
System.out.println("Enter pressed...\n"); } catch (IOException e) { // Handle IO exception
System.err.println(e); // Output the exception
}
System.out.println("Ending main()");
return;
} // Method where thread execution will start
@Override
public void run() {
try {
while(true) { // Loop indefinitely...
System.out.print(firstName); // Output first name
sleep(aWhile); // Wait aWhile msec.
System.out.print(secondName + "\n"); // Output second name
}
} catch(InterruptedException e) { // Handle thread interruption
System.out.println(firstName + secondName + e); // Output the exception
}
} private String firstName; // Store for first name
private String secondName; // Store for second name
private long aWhile; // Delay in milliseconds
}
当程序运行到System.in.read()语句时,会暂停等待用户通过键盘输入数据。用户可以输入一个或多个字符,然后按Enter键。System.in.read()语句只会读取第一个字符,然后继续运行下面的语句。
执行System.in.read()方法将从键盘缓冲区读入一个字节的数据,然而返回的却是16比特的整型量的低位字节是真正输入的数据,其高位字节全是零。当键盘缓冲区中没有未被读取的数据时,执行System.in.read()将导致系统转入阻塞(block)状态。在阻塞状态上,当前流程将停留在上述语句位置且整个程序被挂起,等待用户输入一个键盘数据后,才能继续运行下去;所以程序中有时利用System.in.read()语句来达到暂时保留屏幕的目地。
在TryThread构造函数中,用参数true调用setDaemon()方法会创建后台线程(Daemon Thread)。后台线程是从属于创建它的线程的背景线程,所以当创建它的线程结束时,后台线程也会结束。
用户线程拥有自己的生命周期,而且并不取决于创建它的线程。在创建它的线程结束后,用户线程可以继续执行。包含main()方法的默认线程是用户线程。
注意线程只有的启动前才能调用setDaemon()方法,如果在启动过线程后调用,setDaemon()方法就会抛出IllegalThreadStateException异常。
另外,由后台线程创建的线程也默认为后台线程。
注:daemon英 ['di:mən] 美 ['di:mən]
n. (希腊神话中)半人半神的精灵;守护神;[计]守护进程