线程的状态切换
线程在它的生命周期中会处于各种不同的状态
1.新建态(New)
用new语句创建的线程对象处于新建态,此时它和其他Java对象一样,仅仅在堆区中被分配了内存
2.就绪态(Runnable)
当一个线程对象创建后,其他线程调用它的start()方法,该线程就进入就绪状态,Java虚拟机会为它创建方法调用栈和程序计数器。处于这个状态的线程位于可运行池中,等待获得CPU的使用权
3.运行状态(Running)
处于这个状态的线程占用CPU,执行程序代码。在并发运行环境中,如果计算机只有一个CPU,那么任何时刻只会有一个线程处于这个状态。如果计算机有多个CPU,那么用一时刻可以让几个线程占用不同的CPU,使它们都处于运行状态。只有处于就绪状态的线程才有机会转到运行状态
4.阻塞状态(Blocked)
阻塞状态是指线程因为某些原因放弃CPU,暂时停止运行。当线程处于阻塞状态时,Java虚拟机不会给线程分配CPU,知道线程重新进入就绪状态,它才会有机会转到运行状态。
阻塞状态可分为3种:
(1)位于对象等待池中的阻塞状态(Blocked in object's waitpool):当线程处于运行状态时,如果执行了某个对象的wait方法,Java虚拟机就会把线程放到这个对象的等待池中
(2)位于对象锁池中的阻塞状态(Blocked in object's lockpool):当线程运行处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他线程占用,Java虚拟机就会把这个线程放到这个对象的锁池中
(3)其他阻塞状态,当线程执行了sleep()方法,或者调用了其他线程的join()方法,或者发出了I/O请求,就会进入这个状态。
当一个线程执行System.out.println()或者System.in.read()方法时,就会发出一个IO请求,该线程放弃CPU,进入阻塞状态,直至I/O请求处理完毕,该线程才会回复运行publicimport java.util.Scanner;
public class Machine implements Runnable{
privatestatic StringBuffer log = new StringBuffer();
privatestatic int count = 0;
public voidrun()
{
for(int i=0; i<50; i++)
{
System.out.println(Thread.currentThread().getName()+ ":" + i);
}
}
publicstatic void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
Machine m = new Machine();
Thread t1 = new Thread(m);
t1.start();
int data = in.nextInt();
m.run();
}
}
只有在你输入data后,才会执行主线程。因为主线程由于I/O请求进入阻塞状态,m对象线程占用CPU,直至用户输入数据,主线程才会恢复运行
5.死亡状态(Dead)
当线程退出run()方法时,就进入死亡状态,该线程就结束生命周期。线程有可能是正常执行完run()方法而退出,也有可能是遇到异常而退出。不管线程正常结束还是在运行时因为异常结束,都不会对其他线程造成影响
Thread类的isAlive()方法可以判断一个线程是否或者,当线程处于死亡状态或者新建状态时,该方法返回false,其余状态下,返回true