当JVM加载代码,发现main方法以后,就会启动一个线程,这个线程称为“主线程”(main线程),该线程负责执行main方法。那么在main方法执行中再建立的其余线程就称为程序中的其余线程。java
若是main方法中又建立了其余线程,那么JVM就要在主线程和其余线程之间轮流切换,保证每一个线程都有机会使用CPU资源,main方法即便执行完最后的语句(主线程结束),JVM也不会结束java应用程序,JVM必定要等到Java应用程序中的全部线程都结束以后,才结束java应用程序。spa
java语言使用Thread类及其子类的对象来表示线程,新建的线程在它的一个完整的生命周期中一般要经历以下的四种状态。线程
1.新建code
当一个Thread类或其子类的对象被声明并建立时,新生的线程对象处于新建状态。此时它已经有了相应的内存空间和其余资源。对象
2.运行blog
线程建立以后就具有了运行的条件,一旦轮到它来享用CPU资源时,即JVM将CPU使用权切换给该线程时,此线程就能够脱离建立它的主线程独立开始本身的生命周期。生命周期
线程建立后仅仅是占有了内存资源,在JVM管理的线程中尚未这个线程,此线程必须调用start()方法通知JVM,这样JVM就会知道又有一个新线程排队等候切换了。队列
当JVM将CPU使用权切换给线程时,若是线程是Thread的子类建立的,该类中的run()方法就当即执行,run()方法规定了该线程的具体使命。因此程序必须在子类中重写父类的run()方法,Thread类中的run()方法没有具体内容。内存
在没有结束run()方法前,不要让线程再调用start()方法,不然会发生IIlegalThreadStateException异常。资源
3.中断
有四种缘由的中断。
4.死亡
处于死亡状态的线程不具备继续运行的能力。
线程死亡的缘由有二,一个是正常运行的线程完成了它的所有工做,即执行完run()方法中的所有语句,结束了run()方法;另外一个缘由是线程被强制性地终止,即强制run()方法结束。所谓死亡就是线程释放了实体,即释放分配给线程对象的内存。
代码展现以下所示:
public class Test05 { public static void main(String[] args) { // TODO Auto-generated method stub SpeakElephant speakElephant; SpeakCar speakCar; speakElephant = new SpeakElephant(); speakCar = new SpeakCar(); speakElephant.start(); speakCar.start(); for(int i = 1; i <= 15; i++) { System.out.print("主人" + i + " "); } } }
SpeakCar.java
public class SpeakCar extends Thread{ public void run() { for(int i = 0; i <= 20; i++) { System.out.print("轿车"+ i + " "); } } }
SpeakElephant.java
public class SpeakElephant extends Thread{ public void run() { for(int i = 0; i <= 20; i++) { System.out.print("大象" + i + " "); } } }
运行结果以下所示:
并且每次运行的结果都不同,
线程调度与优先级
处于就绪的线程首先进入就绪队列等候CPU资源,同一时刻在就绪队列中的线程可能有不少个。Java虚拟机中的线程调度器负责管理线程,调度器把线程的优先级分为10个级别,分别用Thread类中的类常量表示。每一个Java线程的优先级都在常数1和10之间。若是没有明确地设置好线程的优先级别,每一个线程的优先级别都为常数5.
线程的优先级经过setPriority(int grade)方法调整,若是参数不在1和10之间,那么会产生异常。