Java的线程状态

操作系统线程状态:

  • NEW(新建):在OS层面线程已被创建,如通过new Thread(runnable)创建一个线程;但是还不允许分配CPU执行。
  • RUNNABLE / READY(就绪):OS线程已被创建,随时可以被CPU调度启用。
  • RUNNING(运行):当有空闲CPU时,OS会将其分配给一个RUNNABLE状态的线程。
  • BLOCKED / WAITING(阻塞/休眠/等待/挂起):阻塞API或等待某个事件(如条件变量),线程就会切换到阻塞状态,同时释放CPU使用。该状态在 Java中被划分为了 BLOCKEDWAITINGTIMED_WAITING 三种状态。当线程调用阻塞式 API时,进程(线程)进入等待状态,这里指的是操作系统层面的。从 JVM层面来说,Java线程仍然处于 RUNNABLE 状态。
  • TERMINATED(终止):线程执行完成,被强行终止或出现异常,就进入终止状态,线程的生命周期结束。

Java线程状态:

  • NEW(新建):Java调用new Thread(),就新建了一个线程。
  • RUNNABLE(运行):调用线程的start()方法创建,因为Java中的Thread是应用层面的API,无法直接感知到内核对线程的操作,因此将操作系统线程的READY和RUNNING统一归到此处的运行状态,即Java中的线程处于RUNNABLE状态时,可能正在执行,也可能没有正在执行,而是在等待被分配CPU资源。(比如RUNNABLE状态的线程的任务运行到一半,执行该线程的CPU被调度去做其他事情,导致该线程暂时不执行,但它的状态依然保持RUNNABLE不变,因为它随时可能被调度回来继续执行任务)
  • BLOCKED(阻塞):由进入synchronized时未获取到监视器锁导致从RUNNABLE进入该状态,或在WAITING / TIMED_WAITING状态下唤醒也可能进入该状态。即正在阻塞等待一个监视器锁(锁对象)的线程处于这一状态(阻塞队列)。
  • WAITING(等待):当调用了没有设置超时时间的wait()方法或遇到join()方法或LockSupport的park()方法时(如ReentrantLock未获取到锁,即进入WAITING状态) 从RUNNABLE进入该状态。处于该状态的线程不会被分配CPU执行时间,且要等待被显式地唤醒。即正在无限等待另一个线程执行一个唤醒动作的线程处于这一状态(等待队列)。与阻塞状态区别:线程在没有拿到锁时是BLOKCED状态,拿到锁后的执行期间,如果因为达不到某些条件,想要暂停等待一会,先不执行,此时调用wait()可以进入WAITING状态,进入WAITING后即释放锁资源,并等待通知机制来唤醒当前线程,唤醒后亦需要重新竞争锁资源。
  • TIMED_WAITING(计时等待):当调用了设置时间参数的sleep() / wait() / join() / parkNanos() / parkUntil()方法时从RUNNABLE进入该状态。处于该状态的线程不会被分配CPU执行时间,在达到一定时间后它们会自动唤醒。
  • TERMINATED(终止)

几种常见方法:

  • Thread.yield():当前线程调用此方法,即放弃获取的CPU时间片,但不释放锁资源,由OS的运行状态变为OS的就绪状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。该方法与sleep()类似,只是不能由用户指定暂停多长时间。
  • Thread.sleep(long millis):当前线程调用此方法,即进入TIMED_WAITING状态,但不释放对象锁,millis后线程自动唤醒进入就绪状态。
  • obj.wait():当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long timeout) 的超时时间到自动唤醒。 与sleep()方法比较:sleep()是让当前线程休眠,不涉及到对象类,也不需要获得对象的锁,所以是线程类的方法。wait() 是让获得对象锁的线程实现等待,前提是要楚获得对象的锁,所以是类的方法,且使用wait()方法必须放在 synchronized 块里面
  • obj.notify():唤醒在此对象监视器上等待的任意单个线程,notifyAll()唤醒在此对象监视器上等待的所有线程。在调用notify()或者notifyAll()后,调用wait()的等待线程不会立刻从等待队列返回,而是从等待队列移动到同步队列,准备竞争对象监视器,即线程状态从WAITING转化为BLOCK。(wait() / notify() / notifyAll()必须配合监视器一起使用,park()和unpark()则不必;unpark()通过传参可以指定要唤醒的线程且unpark()可以在park()执行前就调用一样有效)。
  • t.join():当前线程里调用其它线程t的join方法,当前线程进入WAITING / TIMED_WAITING状态,当前线程不会释放已经持有的对象锁。线程t执行完毕或者millis时间到,当前线程一般情况下进入RUNNABLE状态,也有可能进入BLOCKED状态(因为join()基于wait()实现)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值