wxw*_*wxw 2 java multithreading jvm notify
该join()方法等待线程终止。它用来wait执行此操作。
if (millis == 0) {
while (isAlive()) {
wait(0);
}
}
Run Code Online (Sandbox Code Playgroud)
那么当线程退出时,如何通知wait set中的线程呢?
我尝试在JDK源代码中查找代码,但失败了。谁能告诉我相关的代码片段吗?
当一个线程处于等待状态时,它可能会isAlive()多次检查其时间片,这是浪费吗?
如果isAlive()为 false,则返回,该线程已处于等待集中。有while(isAlive())必要吗?
- 我尝试在JDK源代码中查找代码,但失败了。谁能告诉我相关的代码片段吗?
ThreadOpenJDK jdk8u 源代码树中该类的路径名是jdk/src/share/classes/java/lang/Thread.java。代码join()如下。
发生该情况的本机代码notifyAll位于.Thread::exithotspot/src/share/vm/runtime/thread.cpp
对于其他版本,路径可能不同。(find命令是你的朋友。)
- 当一个线程处于等待状态时,它可能会
isAlive()多次检查其时间片,这是浪费吗?
这是不正确的。
“等待设置”参数不正确。如果当前线程可以调用,则isAlive()它不在任何等待集中。Thread仅当目标处于通话状态时,它才会处于目标的“等待集”中wait(...)。当通知当前线程时,它将从“等待集合”中删除。
重申一下,一个线程在执行时t1处于另一个线程的“等待集中” 。t2t1t2.wait(...)
呼叫wait(0)意味着“等待通知,没有超时”。sleep(0)(它与or的意思不同yield()!)因此,这不是一个繁忙的循环。
该循环通常只会进行零次或一次。(但请参阅我答案的下一部分。)
- 如果 isAlive() 为 false,它只是返回,该线程已经处于等待集中。while(isAlive()) 是必要的吗?
您的“等待设置”逻辑不正确(如上所述)。
循环是必要的。任何引用目标对象的应用程序代码都可以Thread调用Object.notify()该目标对象。这会导致wait(0)返回。但由于这种“唤醒”是虚假的,因此有必要检查目标是否Thread实际上已经结束(通过调用isAlive())并且可能再次等待。
如果应用程序代码做了一些愚蠢的事情,这种情况可能会反复发生……但它不应该。
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
Run Code Online (Sandbox Code Playgroud)
的大部分实现Thread都是在本机代码中。这就是notifyAll唤醒连接线程的地方。
| 归档时间: |
|
| 查看次数: |
153 次 |
| 最近记录: |