Java--多线程(一)------Java 线程的6种状态

在这里插入图片描述

Java中线程的状态分为6种

1、初始(NEW)

创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态。

2、运行(RUNNABLE)

运行态包括就绪(ready)和运行中(running)。

线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。

就绪态:该状态下的线程已经获得执行所需的所有资源,只要CPU分配执行权就能运行,该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权。

运行态:获取到了CPU执行权,处于正在执行的线程。

由于一个CPU同一时刻只能执行一条线程,因此每个CPU每个时刻只有一条运行态的线程。

3、阻塞(BLOCKED)

可以理解为:线程进入synchronized关键字修饰的方法或代码块(即获取锁)失败。

  • 当一条正在执行的线程请求某一资源(锁、IO、Socket)失败时,就会进入阻塞态。

  • 在Java中,阻塞态专指请求锁失败时进入的状态。

  • 由一个阻塞队列存放所有阻塞态的线程。

  • 处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行。

4、等待(WAITING)

处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。

某一线程因为调用下列方法而处于等待状态:

  • 不带超时值的Object.wait方法被调用

  • 不带超时值的Thread.join方法被调用

  • 不带超时值的LockSupport.park方法被调用

waiting状态的线程。处于等待状态的线程在等待另一个线程完成之后才执行特定的操作,通常是在等待cpu。比如,在某个对象上调用Object.wait()的线程,就在等待其他的线程在该对象上调用Object.notify()或Object.notifyAll()之后才会去重新竞争cpu和锁。又或是Thread.join()的线程正在等待制定线程的终止,主线程会等待子线程终止后再继续执行。

  • 线程处于等待态表示它需要等待其他线程的指示才能继续运行。
  • 进入等待态的线程会释放CPU执行权,并释放资源(如:锁)
  • 一个等待队列存放所有等待态的线程

5、超时等待(TIMED_WAITING)

处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。

  • 当运行中的线程调用sleep(long)、wait(long)、join(long)、LockSupport.parkNanos()、LockSupport.parkUntil()时,就会进入该状态;
  • 进入该状态后释放CPU执行权 和 占有的资源。
  • 它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后需要其他线程唤醒;
  • 与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁。

6、终止(TERMINATED)

  • 当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。
  • 线程一旦终止了,就不能复生。
  • 在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

备注:

1、wait()和sleep(long)区别

wait()方法会释放CPU执行权 和 占有的锁。sleep(long)方法仅释放CPU使用权,锁仍然占用

2、yield()

yield()方法仅释放CPU执行权,锁仍然占用,线程会被放入就绪队列,会在短时间内再次执行

3、wait和notify

wait和notify必须配套使用,即必须使用同一把锁调用;wait和notify必须放在一个同步块中调用wait和notify的对象必须是他们所处同步块的锁对象。

参考:https://blog.csdn.net/pange1991/article/details/53860651


如果你觉得本篇文章对你有所帮助的话,麻烦请点击头像右边的关注按钮,谢谢!

技术在交流中进步,知识在分享中传播

发布了166 篇原创文章 · 获赞 212 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/qq_29914837/article/details/103811207