1. 线程有哪6
种状态?
- New:新建,已经创建尚未启动,未执行
start()
- Runnable:可运行的,调用
start()
方法之后;一旦线程调用了start()
方法,线程就会进入Runnable
状态。 对应操作系统中的ready
和running
。 - Blocked:当一个线程进入被
synchronized
修饰的代码后,并且该锁已经被其它线程占用。 - Waiting:没有设置timeout的Object.wait()方法;
- Timed Waiting: 对于
TIMED_WAITING
状态而言,即使没到超时时间,收到Object.notify() Object.notifyAll() LockSuppory.unpark()
也会被唤醒。 - Terminated:线程正常结束;出现没有被捕获的异常导致意外终止
run()
方法。
2. 每个状态
是什么含义?
在代码中演示
BLOCKED
、WAITING
、TIMED_WAITING
状态
/**
* 展示Blocked、Waiting、TimedWaiting
* */
public class BlockedWaitingTimedWaiting implements Runnable{
public static void main(String[] args) throws InterruptedException {
BlockedWaitingTimedWaiting block = new BlockedWaitingTimedWaiting();
Thread thread1 = new Thread(block);
thread1.start();
Thread thread2 = new Thread(block);
thread2.start();
Thread.sleep(100);
//打印出Timed_waiting状态,因为正在执行Thread.sleep(1000)
System.out.println(thread1.getState());//①
//打印出Blocked状态,因为thread2想拿到sync()的锁却拿不到
System.out.println(thread2.getState());//②
Thread.sleep(2300);//③
System.out.println(thread1.getState());//④
System.out.println(thread2.getState());//⑤
System.out.println(thread1.getState());//⑥
System.out.println();
}
@Override
public void run() {
sync();//⑦
}
private synchronized void sync(){
try {
Thread.sleep(2000);//⑧
wait();//⑨
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果:
TIMED_WAITING
BLOCKED
WAITING
TIMED_WAITING
WAITING
Process finished with exit code 130
输出结果分析:
①和②行的输出结果注释已给出,④为什么会输出
WAITING
状态?因为thread1
已经执行完⑧,正在执行wait()
,执行wait()
方法时线程处于WAITING
状态。那⑤呢?④正在执行synchronized
代码块,⑤为什么会输出TIMED_WAITING
?根据Oracle官网说明:
Note that the wait method, as it places the current thread into the wait set for this object, unlocks only this object; any other objects on which the current thread may be synchronized remain locked while the thread waits.
请注意,wait 方法将当前线程放入此对象的等待集中,因此仅解锁此对象; 当前线程可能同步的任何其他对象在线程等待时保持持锁状态。
也就是说
wait()
方法会释放当前线程持有的对象锁,所以⑤会执行同步代码块。
至于⑥,没有唤醒该线程的处理,所以一直处于
WAITING
状态。
3. 状态间的转换图示
状态转换的特殊情况
- 从
Object.wait()
状态刚被唤醒时,通常不能立刻抢到monitor锁,那就会从Waiting
先进入到Blocked
状态,抢到锁再转换到Runnable
状态。 - 如果异常发生,可以直接跳到终止
Terminated
状态,不必再遵循路径,比如可以从Waiting
直接到Terminated
状态。
BLOCKED
public static final Thread.State BLOCKED
Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or
reenter a synchronized block/method after calling Object.wait
.
关于唤醒wait()
方法,Orcale官网还增加了一种方式:
This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. Thread T becomes disabled for thread scheduling purposes and lies dormant until one of four things happens(当前线程因线程调度目的而处于禁用状态并且休眠直到以下四件事任一发生):
- Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be awakened.
- Some other thread invokes the notifyAll method for this object.
- Some other thread
interrupts
thread T.- The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.
4. 阻塞
状态是什么?
一般习惯而言,把
Blocked
(被阻塞)、waiting
(等待)、TimedWaiting
(计时等待)都称为阻塞状态。
不仅仅是
Blocked
5. 常见面试
问题
- 线程的有哪几种状态?生命周期是什么?