Java多线程 - BLOCKED vs WAITING 状态

系列文章:

BLOCKED, WAITING状态描述

当一个线程调用Object.wait 或 Thread.join方法时,线程会进入 WAITING状态。

如果是调用Object.wait,在进入WAITING状态之前,线程会先释放它持有的对象锁,然后保持WAITING状态直到其他线程调用了同一个Object的notify或notifyAll方法。一旦在同一个对象上调用了notify或notifyAll,WAITING状态的线程中的一个或所有将被唤醒。如果对象锁被别的线程持有,则被唤醒的线程不会立即获得对象锁,而是进入BLOCKED状态。当前持有锁的线程一旦释放锁,这些被唤醒线程会比在那些还未进入同步代码块或方法的线程优先获得对象锁。

如果是调用Thread.join,在进入WAITING状态之前,线程不会释放锁,调join方法时也并不需要你一定要持有对象锁才能调。

Object.wait 和 Object.notify/notifyAll 是必须要持有对象锁才可以调用的。

可以看出WAITING状态和锁没有必然联系的,进入WAITING状态和退出WAITING状态都跟对象锁没有关系,虽然Object.wait会导致线程释放对象锁,但那只是Object.wait提供的一个特性,进入WAITING状态并不一定会跟释放锁联系在一起,Thread.join就跟锁没有关系。

BLOCKED和锁有必然的联系,如果线程进入BLOCKED状态,那么它一定是在等待获得锁,退出BLOCKED状态,一定是已经获得了锁。反过来看,如果一个线程获得了锁,会导致其他想要获得锁的线程进入BLOCKED状态,线程释放锁,会导致其他线程争抢锁,抢到锁就退出BLOCKED状态。但是线程获得锁,释放锁对其他处于WAITING状态的线程是没有任何影响的。

另外TIMED_WAITING 除了有个定时唤醒的时间外,本质上和WAITING是一样的。

简而言之,WAITING/TIMED_WAITING 只是线程本身暂停运行的一种状态,可以被外界唤醒或是达到某种条件被唤醒或这被打断(Interrupted)。而BLOCKED是线程本身想要运行,但是被锁给挡住了去路,并随时等待获取锁继续前进的一种状态。

WAITING/TIMED_WAITING 状态是可以被打断的,通过Thread.interrupt方法,也就是为什么Object.wait, Thread.join, Thread.sleep都会声明一个非运行是异常抛出InterruptedException。而BLOCKED的状态是不可以被打断的。

区别总结

进入机制

WAITING/TIMED_WAITING

通过调用:

  • Object.wait
  • Thread.join
  • Thread.sleep
  • LockSupport.park

BLOCKED

等待获得锁已进入同步块/方法,可能是从Object.wait然后唤醒进行等待获得锁。

退出机制

WAITING/TIMED_WAITING

  • 通过调用Object.notify/notifyAll
  • join的线程终止
  • 定时时间到期

BLOCKED

获得锁。

可否能被打断

WAITING/TIMED_WAITING

可被打断,须要捕获InterruptedException异常

BLOCKED

不可被打断

转载于:https://my.oschina.net/shipley/blog/3044949

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值