一,线程状态
新建状态:当一个Thread类或其子类被声明创建时,此时它处于新建状态 ,有了内存空间和其他资源,并已经初始化。
就绪状态:处于新建状态的线程被启动后,等待cpu分配时间片,已经具备了运行的状态,一旦分配到cpu就会脱离主线程,开始自己的生命周期
另外,之前处于阻塞状态的线程,被接触阻塞后,也会回到就绪状态。
运行状态:就绪状态的线程被调度并且获得资源的时候,就处于运行状态,每个Thread类和其子类都有一个重要的方法run(),当线程被调度时,将自动调用本对象的run方 法。run方法定义了的操作和能力。
阻塞状态:一个正在执行的线程,如果在某些情况下让出cpu并将中止执行进入阻塞状态。如果阻塞被解除,依然可以回到就绪状态。
死亡状态:处于死亡状态的线程不具备继续运行的能力。死亡的原有由2个:1.正常地执行完任务。2.被强制中止(destroy(),stop())
二,线程的优先级
线程优先级1-10之间,java虚拟机线程调度是基于优先级的抢先调度机制。在大多数情况下,当前运行的线程优先级要大于或者等于线程池中任何线程的优先级
,但这也是大多数情况。
可以通过setPriority(int newPriority)更改线程的优先级。
线程默认的优先级是5,Thread类中由三个常量,定义线程优先级的范围
static int MAX_PRIORITY 线程可以具有的最高优先级
static int MIN_PRIORITY 线程可以具有的最低优先级
static int NORM_PRIORITY 线程默认优先级
三,阻止线程执行
对于线程的阻止,一般考虑三个方法,不考虑IO阻塞的情况:
睡眠,等待,因为需要一个对象的锁定而被阻塞。
睡眠:public static void sleep() Thread.sleep(long millis) / Thread.sleep(long millis,int naos) 静态方法强制当前正在执行的线程休眠于阻塞状态,当睡眠时间结束,返 回就绪状态。
线程睡眠的原因:线程执行太快,或者需要强制进入下一轮,因为java规范不保证合理的轮换。
注意,run()方法没有异常,所以你只能在内部使用try catch块
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
睡眠的位置,为了让其他线程有机会执行,可以将Thread.sleep()的调用放在线程run()之内。这样才能保证该线程在执行过程中会睡眠。
暂停yield()方法,暂停当前正在执行的线程对象,并执行其他线程。当前运行的线程回到就绪状态。允许让其他具有相同优先级的线程获得运行机会。
join()方法的静态方法让一个线程B加入到另外一个线程A的尾部,在A执行完毕之前,B不可以工作!
四,小结
到目前为止,介绍了新城离开运行状态的几种方法:
public static void sleep(): 使当前线程进入休眠状态,当然,你可以使用中断
public static void yield():不能保障太多的事情,尽管通常他会让当前运行的线程回到可运行状态,使得线程优先级相同的线程有机会执行。
public void join():保证当前线程停止执行,知道该线程加入的线程全部执行完成为止,不过,如果加入的线程没有存活,则当前线程不需要停止。
除了以上三种方式外,还有下面几种特殊的情况使得线程离开运行状态
线程的run()方法完成
在对象上调用wait()方法
线程不能在对象上获得锁定,正试图运行该对象的方法代码
线程调度程序还可以决定当前运行状态移动到就绪状态,以便让另一个线程获得机会。而不需要任何理由。