Java----多线程详解(二)
3、线程状态
线程存在多种状态,包括新状态、可运行状态、运行状态、等待/被阻塞/睡眠/监控/挂起状态和死状态5中状态。
1)、新状态
新状态是指线程实例化后,但start方法还没有在该线程上被调用时所处的状态。它还没有达到准备运行的状态,更不是一个执行线程。
2)、可运行状态
Start()方法启动后,线程由新状态进入可运行状态。可运行状态就是准备好,可以运行但还没有运行的状态。
不但stat()方法可以进入运行状态,而且从等待/被阻塞/睡眠/监控/挂起状态也可以进入可运行状态。如调用sleep()方法结束后,调用yield(0方法结束后所作用的线程都进入可运行状态。
可运行状态也可以说是CPU选择线程的状态。所有的线程不分主次、前后,只要处于可运行状态都有可能被CPU选中运行,当然有可能本线程处于可运行状态,但是很长时间不运行它,这个是一种特殊情况。还有其中情况就是总是运行一个线程,如在一个线程中调用yield()方法后进入可运行状态,但是下面运行的还是这个线程。
3)、运行状态
就是当前执行线程所处的状态,它可以转入可运行状态和等待/被阻塞/失眠/监控/挂起状态,但是只能从可运行状态进入运行状态。
4)、等待/被阻塞/睡眠/监控/挂起状态
等待/被阻塞/睡眠/监控/挂起状态很复杂,它是很多状态的集合体,但是都起到从运行状态到可运行状态的中介作用。处于运行状态的线程由于某种原因不能继续运行,例如调用sleep()方法、被调用join()方法,此线程就会由运行状态进入等待/被阻塞/睡眠/监控/挂起状态。而当sleep()方法结束后或调用join()方法的线程结束后,该线程就又进入可运行状态。
进入等待/被阻塞/睡眠/监控/挂起状态的方法除了sleep()、yield()方法和join()方法外,还有suspend()方法,它是指让一个线程把另一个线程挂起。
5)、死状态
当线程中的run()方法完成之后,线程就进入了死状态。对处于一个死状态的线程带哦用start()方法会发生异常。
4、线程的调度
线程调度程序是JVM中的一部分,它决定在任意指定的时刻应该运行哪个线程,并吧线程带出运行状态。线程的调度定义了java运行环境如何交换任务以及如何选择下一个即将被执行的任务。对线程进行调度又通过优先级、sleep()、yield()、join()方法来完成。在前面说过CPU对线程的选择是不确定的,所以通过调度知识让线程按照某种方式运行,而不能彻底规定它。
1)、优先级
用来判定何时允许某个线程运行。理论上优先级高的线程比优先级低的线程可获得更多的CPU时间。实际上获得CPU时间长度与很多因素有关,不能仅靠优先级来判断。设计线程的优先级使用setPriority(int level)方法来设置。在level值中,用MIN_PRIORITY来表示优先级最小1;用MAX_PRIORITY来表示优先级最大10;线程的默认优先级为5即NORM_PRIORITY。
获得当前线程的优先级的方法是getPriority(),其一般形式为getPriority()。
看下面应用优先级的程序,它通过执行循环、记录次数来表现出优先级的高低:
public class test{ public static void main(String[] str) { MyThread1 t1 = new MyThread1(); MyThread2 t2 = new MyThread2(); MyThread3 t3 = new MyThread3(); t1.start(); t2.start(); t3.start(); }} class MyThread1 extendsThread{ @Override public void run() { for (int i = 0; i < 20; i++) { System.out.print("●"); Thread.yield(); } }} class MyThread2 extendsThread{ @Override public void run() { for (int i = 0; i < 20; i++) { System.out.print("■"); Thread.yield(); } }} class MyThread3 extendsThread{ @Override public void run() { for (int i = 0; i < 20; i++) { System.out.print("▲"); } }}我们对t1和t2执行yield()方法,执行结果会先打印出一连串的三角形,即t3。但让步没有完全成功,在三角形中仍然还有正方形和圆形:
■●▲▲▲▲▲▲▲●■●▲▲■▲▲▲▲▲▲▲▲▲▲▲●■■●■●■●●■●●■●●●■●■●■●■●■●■●■●■■■■成功构建 (总时间: 0 秒)