Java线程的第一种实现方式,主要分两步,第一步是继承java.lang.Thread; 第二步是重写run()方法。接下来我们来看Java线程的第二种实现方式,也是分为两步,第一步,写一个类实现java.lang.Runnable;接口; 第二步,实现run()方法。结合以下代码来看。
public class ThreadTest03{
public static void main(String[] args){
//创建线程
Thread t=new Thread(new Processor());
//启动线程
t.start();
}
}
//写一个类实现Runnable接口
class Processor implements Runnable{
public void run(){
for(int i=0;i<10;i++){
System.out.println("run--->"+i);
}
}
}
上述代码中,创建线程的时候使用的是构造方法,打开jdk的帮助文档,
Thread(Runnable target) ,括号里的参数是Runnable类型的,Processor类实现了Runnable接口,因此可以使用new Processor()创建对象作为Thread()的方法,即Thread t=new Thread(new Processor());。
第二种方式与第一种方式要注意区分,为了看得更清楚一点,我们把第一种实现方式的代码放到下边。
public class ThreadTest02{
public static void main(String[] args){
//创建线程(多态:父类型引用指向子类型对象)
Thread t=new Processor();
//启动
t.start();
for(int j=0;j<10;j++){
System.out.println("main--->"+j);
}
}
}
//自定义一个线程
class Processor extends Thread{
//重写run方法
public void run(){
for(int i=0;i<100;i++){
System.out.println("run--->"+i);
}
}
}
第一种实现方式中,因为Processor类继承了Thread,所以Processor本身就是一个线程,在main()方法中创建线程的时候直接new Processor(); 而第二种实现方式中,因为Processor实现的是Runnable接口,它本身不是一个线程,只不过是一个实现了Runnable接口可运行的类。创建线程的时候使用的是Thread的构造方法Thread t=new Thread(Runnable target); 可以new出一个Processor类的对象作为Thread()构造方法的参数。
线程的生命周期
当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过新建、就绪、运行、阻塞和死亡5种状态。尤其是当线程启动以后,它不可能一直"霸占"着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。
1. 新建状态,当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存,并初始化其成员变量的值。此时的线程对象没有表现出任何线程的动态特征,程序也不会执行线程的线程执行体。
2. 就绪状态,当线程对象调用了start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行。处于这个状态中的线程并没有开始运行,只是表示该线程可以运行了。至于该线程何时开始运行,取决于JVM里线程调度器的调度。
3. 运行状态,如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态。
4. 阻塞状态,当处于运行状态的线程失去所占用资源之后,便进入阻塞状态。
5. 线程会以如下3种方式结束,结束后就处于死亡状态:
① run()或call()方法执行完成,线程正常结束。
② 线程抛出一个未捕获的Exception或Error。
③ 直接调用该线程stop()方法来结束该线程——该方法容易导致死锁,通常不推荐使用。
wx搜索“程序员考拉”,专注java领域,一个伴你成长的公众号!