程序的一次执行称为进程(process)。一个进程包括一个程序模块和该模块一次执行时所处理的数据。
线程(thread)是指进程内部一段可独立执行的有独立控制流的指令序列。
Java的线程由java.lang中定义的类Thread来实现; 当创建一个Thread类的对象,就产生一个线程对象,线程对象可启动线程、终止线程、或者暂时挂起线 程等; Thread类本身只是线程的虚拟CPU; 线程所执行的代码(或者说线程所要完成的功能)是通过方法 run( )(包含在一个特定的对象中)来完成的,方法run( )称为线程体。
Thread类的构造方法如下: public Thread( ThreadGroup group, Runnable target, String name)
Group:指明了线程所属的线程组; target:是线程体run()方法所在的对象; name:是线程的名称。 target必须实现接口Runnable。在接口Runnable中只定义了 一个方法void run()作为线程体; 任何实现接口Runnable的对象都可以作为一个线程的目标对象。上述构造方法中的参数可有也可以没有。
从Thread类的构造方法可以看出,用户可以有两种方法构造自己的run( )方法;
方法一:Thread类
定义一个继承Thread的线程类,并重写其中的方法run(); 在初始化这个类的实例时,目标对象target可以为null,表示这个实例本身具有线程体。由于Java只支持单继承,用这种方法定义的类不能再继承其他类。
例:继承Thread类创建线程
public class Thread001 extends Thread{
int k;
public Thread001(String name,int k){
super(name);
this.k=k;
}
public void run() {
int i=k;
System.out.print(getName()+":");//getName()获取线程名称
while(i<100) {
System.out.print(i+" ");
i+=2;
}
System.out.print(getName()+"end");
}
public static void main(String[] args) {
Thread001 t1=new Thread001("Thread1",1);
Thread001 t2=new Thread001("Thread2",2);
t1.start();
t2.start();
System.out.println("activeAccount:"+t2.activeCount());
//activeCount()活动线程个数
}
}
方法二: Runnable接口
提供一个实现接口Runnable的类作为线程的目标对象。在初始化一个Thread类或子类生成线程实例时,把目标对象传递给这个线程实例,由该目标对象提供线程体run()方法; 这时,实现接口Runnable的类还可以再继承其他类,即实现接口Runnable的类可以不单纯是提供线程体。
例:实现Runnable接口创建线程
public class Runnable001 implements Runnable{
int k;
public Runnable001(int k) {
this.k=k;
}
public void run() {
int i=k;
while(i<100) {
System.out.print(i+" ");
i+=2;
}
}
public static void main(String[] args) {
Runnable001 r1=new Runnable001(1);
Runnable001 r2=new Runnable001(2);
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
t1.start();
t2.start();
}
}
两种创建线程方法的比较:
Runnable接口
可以将线程的虚拟CPU、代码和数据分开,形成一个比较清晰的模型; 使得包含线程体的类还可以继承其他类;
直接继承Thread类
不能再继承其他类,但编写简单,并可直接操纵线程;
在具体应用中,采用哪种方法来构造线程体要根据具体情况而定; 通常,当一个线程体所在的类已经继承了另一个类时,就应该用实现Runnable接口的方法。