2.多线程的状态
1.操作系统的生命周期
- 初始状态,线程被创建,这个线程被创建是编程语言级别的线程创建,操作系统还没创建
- 可运行:线程可以分配CPU,表示真正的操作系统线程以及被创建,可以分配CPU了
- 运行:操作系统把CPU分配给了一个可运行状态的线程
- 休眠:运行状态的CPU调用阻塞API就变成了休眠状态
- 终止:线程执行完或者异常退出
在计算机语言层面,对于这五种状态,有些做了合并,对于Java语言,把可运行状态和运行状态合并了
2.Java线程的生命周期
Java语言有6种状态
- NEW(初始化状态)
- RUNNABLE(可运行 / 运行状态)
- BLOCKED(阻塞状态)
- WAITING(无时限等待)
- TIMED_WAITING(有时限等待)
- TERMINATED(终止状态)
在操作系统层面,BLOCKED、WAITING、TIMED_WAITING是同一种状态,就是休眠状态
1. RUNNABLE 与 BLOCKED 的状态转换
线程等待 synchronized 的隐式锁
2.RUNNABLE 与 WAITING 的状态转换
- 获得 synchronized 隐式锁的线程,调用无参数的 Object.wait() 方法
- 调用无参数的 Thread.join() 方法
- 调用 LockSupport.park() 方法
3. RUNNABLE 与 TIMED_WAITING 的状态转换
- 调用带超时参数的 Thread.sleep(long millis) 方法
- 获得 synchronized 隐式锁的线程,调用带超时参数的 Object.wait(long timeout) 方
法 - 调用带超时参数的 Thread.join(long millis) 方法
- 调用带超时参数的 LockSupport.parkNanos(Object blocker, long deadline) 方法
- 调用带超时参数的 LockSupport.parkUntil(long deadline) 方法
4. 从 RUNNABLE 到 TERMINATED 状态
线程执行完 run() 方法后,会自动转换到 TERMINATED 状态,当然如果执行 run() 方法的
时候异常抛出,也会导致线程终止
stop() 和 interrupt()
stop()方法会杀死线程,如果线程持有 ReentrantLock 锁,被stop()的线程并不会自动调用 ReentrantLock 的 unlock()去释放锁,那其他线程就再也没机会获得 ReentrantLock 锁,这个操作很危险
interrupt() 方法仅仅是通知线程,线程有机会执行一些后续操作,同时也可以无视这个通知