挑错 |《Java 并发编程的艺术》中关于线程状态的三处错误
低并发编程
共 3984字,需浏览 8分钟
·
2021-03-25 21:07
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis)
throws InterruptedException {
...
if (millis == 0) {
while (isAlive()) {
wait(0);
}
}
...
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(...);
t.start();
t.join();
System.out.println("此处 t 线程结束后才能输出");
}
// Thread.java
// 无参的 join 有用的信息就这些,省略了额外分支
public synchronized void join() {
while (isAlive()) {
wait();
}
}
hotspot/src/share/vm/runtime/thread.cpp
void JavaThread::exit(...) {
...
ensure_join(this);
...
}
static void ensure_join(JavaThread* thread) {
...
lock.notify_all(thread);
...
}
线程状态从 RUNNABLE 变为 BLOCKED,当且仅当进入 synchronized 方法或 synchronized 块。
/**
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* 在如下场景下等待一个锁(获取锁失败)
* 1. 进入 synchronized 方法
* 2. 进入 synchronized 块
* 3. 调用 wait 后(被 notify)重新进入 synchronized 方法/块
*/
BLOCKED,
当一个阻塞在 wait 的线程,被另一个线程 notify 后,重新进入 synchronized 区域,此时需要重新获取锁,如果失败了,就变成 BLOCKED 状态。
wait 后线程会进入该对象的等待队列,线程状态变为 WAITING。
当被另一个线程执行 notify 时,需要重新竞争锁,如果获取不到,就会进入该对象的同步队列,线程状态变为 BLOCKED。
WAITING -- BLOCKED
评论