31-请描述线程的生命周期

一图胜千言!

Snipaste_2021-05-03_11-03-01

灵魂画家出品。

上述的图有些简略,下面详细说明下,线程共有6种状态:

new,runnable,blocked,waiting,timed waiting,terminated

1,当进入synchronized同步代码块或同步方法时,且没有获取到锁,线程就进入了blocked状态,直到锁被释放,重新进入runnable状态

2,当线程调用wait()或者join时,线程都会进入到waiting状态,当调用notify或notifyAll时,或者join的线程执行结束后,会进入runnable状态

3,当线程调用sleep(time),或者wait(time)时,进入timed waiting状态,

当休眠时间结束后,或者调用notify或notifyAll时会重新runnable状态。

4,程序执行结束,线程进入terminated状态

案例篇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* @author huangguizhao
* 测试线程的状态
*/
public class ThreadStateTest {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Task());
System.out.println(thread.getState());//NEW
thread.start();
System.out.println(thread.getState());//RUNNABLE
//保险起见,让当前主线程休眠下
Thread.sleep(10);
System.out.println(thread.getState());//terminated
}
}
class Task implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class ThreadStateTest {
public static void main(String[] args) throws InterruptedException {
BlockTask task = new BlockTask();
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
//从严谨的角度来说,t1线程不一定会先执行,此处是假设t1先执行
System.out.println(t1.getState());//RUNNABLE
System.out.println(t2.getState());//BLOCKED
Thread.sleep(10);
System.out.println(t1.getState());//TIMED_WAITING
Thread.sleep(1000);
System.out.println(t1.getState());//WAITING
}
}

class BlockTask implements Runnable{

@Override
public void run() {
synchronized (this){
//另一个线程会进入block状态
try {
//目的是让线程进入waiting time状态
Thread.sleep(1000);
//进入waiting状态
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

注意:

blocked,waiting,timed waiting 我们都称为阻塞状态

上述的就绪状态和运行状态,都表现为runnable状态