image.png

线程状态

线程一共有6种状态。
NEW(初始状态)
RUNNABLE(可运行状态)
BLOCKED(阻塞状态)
WAITING(等待状态)
TIME_WAITING(超时等待状态)
TERMINATED(终止状态)

NEW(初始状态)

当实例化出一个线程时,此时线程状态为NEW状态。
方法一:继承Thread类
方法二:实现Runnable接口

RUNNABLE (可运行状态、就绪/运行中状态)

就绪状态: Thread.start()调用 、Thread.sleep()结束、Object.notify()调用、Object.notifyAll() 调用、Thread.yield()调用、获取对象锁
运行中状态:线程获取到CPU的使用权

BLOCKED (阻塞状态)

线程等待进入synchronized同步代码块或同步方法 —-> 获取到锁
lock?

WAITING (等待状态)

Object.wait()调用、Thread.join()调用

TIME_WAITING(超时等待状态)

Thread.sleep()调用、Object.wait(long)调用、Thread.join(long)调用

TERMINATED (终止状态)

线程run()方法执行完毕,或者主线程main()方法执行完毕,则线程终止
在一个终止的线程调用start()方法,会抛出 java.lang.IllegalThreadStateException异常

线程状态之间的交换

NEW到RUNNABLE状态

image.png

  1. TestThread testThread = new TestThread();
  2. Thread thread = new Thread(testThread);
  3. thread.start();

RUNNABLE到BLOCKED状态

image.png

  1. public class Account {
  2. public void draw(int aount) {
  3. synchronized(this) {
  4. // 伪代码
  5. }
  6. }
  7. }
  8. // 或者
  9. public synchronized void drawMethod(int aount) {
  10. // 伪代码
  11. }

RUNNABLE到WAITING状态

image.png
三种场景会触发RUNNABLE到WAITING的转换:
1、获得synchronized隐式锁的线程,调用了Object.wait()方法;
2、调用线程同步Thread.join()方法;

比如有一个线程对象thread A ,当调用A.join()的时候,执行这条语句的线程会等待threadA执行完,其线程状态会从RUNNABLE转换为WAITING。 当线程threadA执行完,原来等待它的线程又会从WAITING状态转换到RUNNABLE。

3、调用LockSupport.park()方法。

Java并发包中的锁,都是基于LockSupport对象实现的。 调用LockSupport.park()方法,当前线程会阻塞,线程状态会从RUNNABLE转换到WAITING。 调用LockSupport.unpark(Thread) 方法,可唤醒目标线程,目标线程状态又会从WAITING状态转换到RUNNABLE状态。

  1. synchronized(object) {
  2. try {
  3. object.wait();
  4. }catch(InterruptedException e) {
  5. e.printStackTrace();
  6. }
  7. }

RUNNABLE到TIME_WAITING状态

image.png
5种场景会触发RUNNABLE向TIME_WAITING转换
1、调用带超时参数的Thread.sleep(long millis)方法;
2、获得synchronized隐式锁的线程,调用带超时参数的Object.wait(long timeout)方法;
3、调用带超时参数的Thread.join(long millis)方法;
4、调用带超时参数的LockSupport.parkNanos(Object blocker, long deadline方法;
5、调用带超时参数的LockSUpport.parkUntil(long deadline)方法。

RUNNABLE到TERMINATED状态

image.png
2种场景触发RUNNABLE到TERMINATED状态
1、异常中断(interupt方法);
2、run方法执行完毕。