Java线程的6种状态转换
Java线程的生命周期
与操作系统中线程的五种状态区分开,Java线程有以下6种状态:
- New 新建
- Runnable 可运行
- Blocked 阻塞
- Waiting 等待
- Timed waiting 计时等待
- Terminated 终止
· 通过调用getState方法,可以获取到一个线程的当前状态;
New 新建状态
- New代表一个线程已经创建,但是还没有启动的状态。当我们使用new Thread()新建一个线程,如果线程没有运行start()方法,那么此时的线程的状态,就是New状态。而一旦调用了start方法,那么线程就从New变成了Runnable。
Runnable可运行状态
一旦调用start方法,线程就进入了Runnable状态。
- java中的Runnable状态,对应操作系统中的两种状态,分别是就绪态和运行态。 也就是说,处于Runnable状态的线程,可能正在执行,也可能没有执行。
- 所以说,如果一个正在运行的线程是Runnable状态,当它运行到一半,执行该线程的CPU被调度去做其他事情,该线程暂停运行,此时该线程仍处于Runnable
状态,因为它随时有可能被调度回来继续执行任务。
Blocked 被阻塞状态
- Runnable状态进入Blocked状态的途径:进入synchorized代码块时,但是没有获得monitor锁。
- 退出Blocked状态的途径:当其他线程释放了这个锁,并且线程调度器允许该线程持有这个锁的时候,它就会变回Runnable状态
Waiting 阻塞状态
- 对于waiting状态的进入,有三种情况,分别是:
- 线程调用了没有timeout参数的Object.wait()方法
- 线程调用了没有timeout参数的Thread.join()方法
- 线程调用了Locksupport.park()方法
Locksupport.park()方法
关于Locksupport.park,在这里说一下,通过上边,我们知道:Blocked状态是针对monitor锁的,但是除了synchronized锁,Java中还有其他的锁,比如说ReentrantLock,
在这些锁中,如果线程没有获取到锁,会直接进入waiting状态,实质上是执行了Locksupport.park()方法才进入waiting方法的。
Timed Waiting 超时等待状态
- 带有超时参数的以下方法,会使线程进入超时等待
- Object.wait(long timeout);
- Thread.sleep(long mills);
- Thread.join(long mills);
- LockSupport.parkNanos(long mills);
- LockSupport.parkUntil(long mills);
Blocked 和 Waiting 的区别
- Blocked 等待其他线程释放这个锁
- Waiting 等待某个条件的出现,比如: join的线程执行完毕,或者notify,notifyAll
Terminated 终止状态
- 两种情况会导致终止状态
- 第一种: run方法执行完毕,线程自然终止
- 第二种: 因为一个未捕获的异常,导致线程终止