理论
线程的状态分为:
- 新建(NEW):线程对象对象刚被创建,执行start()之前。
- 可运行(RUNNABLE):线程对象创建后,调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度器选中,获取cpu的使用权 。
- 运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
- 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,暂时停止运行。 死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。
- 死亡的线程不可再次复生。
阻塞的情况分三种:
- 等待阻塞:运行(running)的线程执行wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
- 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
- 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
class MyThread extends Thread{
}
public class ThreadTest {
public static void main(String[] args) {
MyThread thread = new MyThread();
System.out.println(thread.getState()); //NEW
thread.start();
System.out.println(thread.getState()); //RUNNABLE
}
}
示例:展示线程的运行和阻塞状态
class MyThread extends Thread {
private String name;
private byte[] lock;
public MyThread(String name, byte[] lock) {
this.name = name;
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name + " OK");
}
}
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
byte[] lock = new byte[0];
MyThread thread1 = new MyThread("thread1", lock);
thread1.start();
System.out.println(thread1.getState()); //RUNNABLE
MyThread thread2 = new MyThread("thread2", lock);
thread2.start();
Thread.sleep(1500);
System.out.println(thread2.getState()); //BLOCKED
}
}