吃透 Java 线程状态:阻塞 VS 等待,notify 与 notifyAll 的本质区别
·
阻塞和等待有啥区别
阻塞是争抢锁失败后被动触发、等待是人为主动触发
阻塞是持锁线程结束后自动唤醒,而等待需要人为用特定的方法唤醒
触发方式:阻塞是在争抢sychronized锁过程中失败后触发,一直到持有锁的线程结束再次争夺锁;WATING是通过Object.wait()方法来触发,此时线程必须持有锁才能触发,而Thread.join()、LockSupport.park()触发的话就不需要持有锁,也不会占用cpu资源
唤醒方式:需要等到持锁线程执行结束再次自动唤醒,而WATING的话如果是wait()进入的就需要用其对象的notify()或notifyAll()这样的方法来唤醒,若是Thread.join()等待执行线程结束后即可唤醒,LockSupport.park()的话需要用LockSupport.unpark(thread)
等待状态下的线程如何进行恢复到运行状态?
核心机制是通过外部事件触发或资源可用性变化,比如等待的线程被其他线程唤醒
synchronized (lock) {
// 线程进入等待状态,释放锁
lock.wait();
}
// 其他线程调用以下代码唤醒等待线程
synchronized (lock) {
lock.notify(); // 唤醒单个线程
// lock.notifyAll(); // 唤醒所有等待线程
}
notify(通知)和notifyAll有什么区别?
都是唤醒线程、都是唤醒线程来竞争锁、都是无法确定谁来竞争锁
notify:唤醒一个线程,让唤醒的线程来拿到锁执行线程,执行线程后如果该线程没有调用notify,那么其他线程都没有办法来苏醒得到锁
notifyAll:唤醒所有的线程,让所有的线程来争夺同一个锁,只有一个线程才能得到锁,得到锁的线程结束后,其他线程还可以争抢锁,直到一个对象的线程所有执行完成
notify选择哪个线程唤醒?
notify 在注释中提到,但是 notify 选择唤醒线程的源码是任意的,依赖于具体实现的 jvm。
比较流行实现的jvm就是hotspot(热点),其唤醒顺序是先进入对象等待队列的线程先唤醒,也就是说先调用wait()方法的线程优先唤醒
更多推荐




所有评论(0)