如何创建线程?如何实现Runnable接口?

107 阅读3分钟

大多数情况,通过实例化一个Thread对象来创建一个线程。Java定义了两种方式: · 实现Runnable 接口。 · 可以继承Thread类。

下面的先介绍了第一种方式: 实现Runnable接口

创建线程的最简单的方法就是创建一个实现Runnable 接口的类。Runnable抽象了一个执行代码单元。你可以通过实现Runnable接口的方法创建每一个对象的线程。为实现Runnable 接口,一个类仅需实现一个run()的简单方法,该方法声明如下:

public void run( ) 

在run()中可以定义代码来构建新的线程。理解下面内容是至关重要的:run()方法能够像主线程那样调用其他方法,引用其他类,声明变量。仅有的不同是run()在程序中确立另一个并发的线程执行入口。当run()返回时,该线程结束。

在你已经创建了实现Runnable接口的类以后,你要在类内部实例化一个Thread类的对象。Thread 类定义了好几种构造函数。我们会用到的如下:

Thread(Runnable threadOb, String threadName) 

该构造函数中,threadOb是一个实现Runnable接口类的实例。这定义了线程执行的起点。新线程的名称由threadName定义。建立新的线程后,它并不运行直到调用了它的start()方法,该方法在Thread 类中定义。本质上,start() 执行的是一个对run()的调用。

Start()方法声明如下:

// Create a second thread. 
class NewThread implements Runnable { 
 Thread t; 
 NewThread() { 
 // Create a new, second thread 
 t = new Thread(this, "Demo Thread"); 
 System.out.println("Child thread: " + t); 
 t.start(); // Start the thread 
 } 
 // This is the entry point for the second thread. 
 public void run() { 
 try { 
 for(int i = 5; i > 0; i--) { 
 System.out.println("Child Thread: " + i); 
 Thread.sleep(500); 
 } 
 } catch (InterruptedException e) { 
 System.out.println("Child interrupted."); 
 } 
 System.out.println("Exiting child thread."); 
 } 
} 
class ThreadDemo { 
 public static void main(String args[]) { 
 new NewThread(); // create a new thread 
 try { 
 for(int i = 5; i > 0; i--) { 
 System.out.println("Main Thread: " + i); 
 Thread.sleep(1000); 
 } 
 } catch (InterruptedException e) { 
 System.out.println("Main thread interrupted."); 
 } 
 System.out.println("Main thread exiting."); 
 } 
}

在NewThread 构造函数中,新的Thread对象由下面的语句创建:

t = new Thread(this, "Demo Thread"); 

通过前面的语句this 表明在this对象中你想要新的线程调用run()方法。然后,start() 被调用,以run()方法为开始启动了线程的执行。这使子线程for 循环开始执行。

调用start()之后,NewThread 的构造函数返回到main()。当主线程被恢复,它到达for 循环。两个线程继续运行,共享CPU,直到它们的循环结束。该程序的输出如下:

Child thread: Thread[Demo Thread,5,main] 
Main Thread: 5 
Child Thread: 5 
Child Thread: 4 
Main Thread: 4 
Child Thread: 3 
Child Thread: 2 
Main Thread: 3 
Child Thread: 1 
Exiting child thread. 
Main Thread: 2 
Main Thread: 1 
Main thread exiting. 

如前面提到的,在多线程程序中,通常主线程必须是结束运行的最后一个线程。实际上,一些老的JVM,如果主线程先于子线程结束,Java的运行时间系统就可能“挂起”。

前述程序保证了主线程最后结束,因为主线程沉睡周期1000毫秒,而子线程仅为500毫秒。这就使子线程在主线程结束之前先结束。简而言之,你将看到等待线程结束的更好途径。