9. 线程生命周期
大约 2 分钟
一、线程生命周期一
线程生命周期如下:
1.线程创建后状态为NEW 2.线程启动后状态从NEW变为RUNNABLE 3.线程调用同步代码块未获得同步锁时状态为BLOCK,如果获取到锁则状态为RUNNABLE 4.线程运行结束后状态为TERMINATED
验证代码如下:
public class LifeCycleDemo {
public static void main(String[] args) {
Thread t0 = new Thread(new Runnable() {
public void run() {
Counter.increase();
}
});
Thread t1 = new Thread(new Runnable() {
public void run() {
Counter.increase();
}
});
//创建后状态为NEW
printState(t0);
printState(t1);
t0.start();
t1.start();
//启动后状态为RUNNABLE
printState(t0);
printState(t1);
sleep(1000);
//运行后t0获得同步锁,进入代码块执行Thread.sleep后状态变为TIMED_WAITING,t1等待获取同步锁,状态为BLOCKED
printState(t0);
printState(t1);
sleep(4000);
//线程执行完后状态为TERMINATED
printState(t0);
printState(t1);
System.out.println("count: " + Counter.getCount());
}
private static void printState(Thread t) {
System.out.println(t.getName() + " " + t.getState());
}
private static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Counter {
private static int count;
public synchronized static void increase() {
count = count +1;
try {
//模拟并发争用
Thread.sleep(2000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
public static int getCount() {
return count;
}
}
打印日志:
Thread-0 NEW
Thread-1 NEW
Thread-0 RUNNABLE
Thread-1 RUNNABLE
Thread-0 BLOCKED
Thread-1 TIMED_WAITING
Thread-0 TERMINATED
Thread-1 TERMINATED
count: 2
二、线程生命周期二
验证代码如下:
public class LifeCycleDemo2 {
public static void main(String[] args) {
Thread t0 = new Thread(new ChildThread(Thread.currentThread()));
t0.start();
//子线程启动后状态为RUNNABLE
printState(t0);
try {
//子线程join后,主线程状态为WAITING
t0.join();
//主线程状态为RUNNABLE
printState(Thread.currentThread());
//子线程运行结束,状态为TERMINATED
printState(t0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void printState(Thread t) {
System.out.println(t.getName() + " " + t.getState());
}
}
class ChildThread implements Runnable {
Thread parentThread;
public ChildThread(Thread parentThread) {
this.parentThread = parentThread;
}
public void run() {
try {
Thread.sleep(2000);
//这里是在子线程join之后打印,此时主线程状态为WAITING
System.out.println(parentThread.getName() + " " + parentThread.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出日志:
Thread-0 RUNNABLE
main WAITING
main RUNNABLE
Thread-0 TERMINATED
其他场景不在单独列出代码。
三、线程生命周期三
这里和前面的区别是方法参数中增加了时间参数,不再举例验证。