线程实现的两种方式
一、继承Thread类
Thread类是Java.lang包中的一个类,从类中实例化的对对象代表线程,启动一个新线程需要建立Thread实例
Thread构造方法如下:
public Thread():创建一个新的线程对象.
public Thread(String ThreadName):创建一个名称为ThreadName的线程对象.
继承Thread类创建一个新的线程语法如下:
public class ThreadTest extends Thread{ }
完成线程真正功能的代码放在类的run()方法中,当一个类继承Thread类后,就可以在该类中覆盖run()方法,将实现该线程功能的代码写入run()方法中,然后同时调用Thread类中的start(0方法执行线程,也就是调用run()方法.
Thread对象需要一个任务来执行,任务是指线程在启动时执行的工作,该工作功能代码被写在run()方法中.
run()方法语法格式:
public void run(){
}
注意:
如果start()方法调用一个已经启动的线程,系统将抛出IllegalThreadException异常
当执行一个线程程序时,就会自动但产生一个线程,主方法正是在这个线程上运行.当不启动其他线程时,该程序就是单线程程序
启动线程代码如下:
Public static void main(System[] args){ new ThreadTest().start(); }
例1:
在项目中创建ThreadTest类,该类继承Thread类方法创建线程
package 继承Thread类; public class ThreadTest extends Thread { // 指定类继承Thread类 private int count = 10; public void run() { // 重写run()方法 while (true) { System.out.println(count + " "); // 打印count变量 if (--count == 0) { // 使用count变量自减,当自减为0时,退出循环 return; } } } public static void main(String[] args) { new ThreadTest().start(); } }
运行结果:
上述实例,继承了Thread类,然后在类中覆盖了run()方法.通常使用无限循环的形式,是得线程一直进行下去,所以要指定一个跳出循环的条件,如在本实例中使用变量count递减为0作为跳出循环的条件.
在main方法中,使线程执行需要调用Thread类中的start()方法,start()方法调用被覆盖的run()方法,如果不掉用start()方法,线程永远不会启动,在主方法没调用start()方法之前,Thread对象只是一个实例而不是线程.
二、实现Runnable接口
一个扩展Jframe类的GUI程序不可能再继承Thread类,因为Java不支持多继承.如果要使用当前类实现多线程,可以通过Runnable接口实现.
实现Runnable接口语法如下:
public class Thread extends Object implements Runnable
说明:
实质上Thread类实现了Runnable接口,其中的run()方法正是对Runnable接口中的run()方法的具体实现.
实现Runnable接口的程序创建一个Thread对象,并将Runnable对象与Thread对象相关联.
Thread类中有以下两个构造方法:
public Thread(Runnable target)
public Thread(Runnable target,String name)
这两个构造方法的参数中存在Runnable实例,使用以上构造方法就可以将Runnable实例与Thread实例相关联.
使用Runnable接口启动新的线程的步骤如下;
(1)建立Runnable对象
(2)使用参数为Runnable对象的构造方法创建Thread实例
(3)调用start()方法启动线程
通过Runnable接口创建线程时,首先需要编写一个实现Runnable接口的类,然后实例化该类的对象,这样就建立了Runnable对象;接下来使用相应的构造方法创建Thread实例;最后使用该实例调用Thread类中的start()方法启动线程.图1表明实现Runnable接口创建线程的流程
图1
例2
实现Runnable接口方式创建线程
package Example2; /** * 实现Runnable接口方式创建线程 * @author yangf * */ public class MyRunnable implements Runnable{//实现Runnable接口 @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+":"+i); } } public static void main(String[] args) { //1.创建线程对象 Runnable myRunnable = new MyRunnable(); // Thread t = new Thread(myRunnable,"MyThread"); t.start();//启动线程 } }
运行结果:0到99
注意:
启动一个新的线程,不是直接调用Thread子类对象的run()方法,而调用Thread子类的start()方法,Thread类的start()方法产生一个新的线程,该线程运行Thread子类的run()方法.
三、总结
线程对象调用start()方法和调用run()方法区别:
run():只有主线程一条执行路径
start():多条执行路径,主线程和子线程并行交替执行