1) Я пытаюсь найти код в исходном коде JDK, но не получилось.Может кто-нибудь показать мне соответствующие фрагменты кода?
Путь к классу Thread
в дереве исходных текстов OpenJDK jdk8u - jdk/src/share/classes/java/lang/Thread.java
.Код для join()
приведен ниже.
Собственный код, где встречается notifyAll
, находится в Thread::exit
в hotspot/src/share/vm/runtime/thread.cpp
.
Для других выпусков пути могут отличаться.(Команда find
- ваш друг.)
2) Когда поток в наборе ожидания установлен, он может столько раз проверять isAlive()
свой временной интервал, это пустая трата?
Это неверно.
Неверный аргумент "set wait".Если текущий поток может вызвать isAlive()
, он не находится в любом установленном ожидании.Он будет только в «наборе ожидания» для цели Thread
, когда он находится в wait(...)
вызове.Он удаляется из «набора ожидания», когда текущий поток уведомляется.
Повторюсь, поток t1
находится в «наборе ожидания» другого потока t2
, когда t1
выполняется t2.wait(...)
.
Вызов wait(...)
с нулевым тайм-аутом означает «дождаться уведомления без тайм-аута ».Следовательно, это не занятый цикл.
Цикл будет обычно вращаться вокруг нуля или только один раз.(Но смотрите следующую часть моего ответа.)
3) Если isAlive () имеет значение false, он просто возвращает, этот поток уже находится в состоянии ожидания.Требуется ли while (isAlive ())?
Ваша логика "установки ожидания" неверна (как указано выше).
Цикл необходим.Для любого кода приложения, имеющего ссылку на целевой объект Thread
, можно вызвать Object.notify()
для него.Это заставляет wait(0)
вернуться.Но так как это «пробуждение» является ложным, необходимо проверить, что цель Thread
действительно закончилась (вызывая isAlive()
) и, возможно, снова waitinf.
Это может происходить многократно ... если код приложения делает что-то глупое ... но это не должно быть.
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;
}
}
}
Большая часть реализации Thread
находится в собственном коде.Вот где создается notifyAll
, который пробуждает присоединяющиеся нити.