Waiting for Horse_01
Horse_08 has finished the race!
Horse_04 has finished the race!
Horse_05 has finished the race!
Horse_01 has finished the race!
Horse_06 has finished the race!
Horse_03 has finished the race!
Horse_07 has finished the race!
Horse_02 has finished the race!
Waiting for Horse_02
Horse_09 has finished the race!
Horse_10 has finished the race!
Waiting for Horse_09
Причем не важно в какой последовательности стоят join() и вывод строки.Анна
28 уровень
Почему получается подобный вывод?
Архивный
Комментарии (5)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
IceBergMaster
30 января 2019, 10:09решение
join() не заставляет всех лошадей ждать, а только метод который его вызывает, т.е. сначала метод calculateHorsesFinished() станет и будет ждать пока финиширует первая лошадь, а вот остальные в этот момент будут бежать. Если вы касательно порядка, то нити это как квантовая физика).
+2
Dima
9 февраля 2019, 17:24
Добрый день! Прошу помощи - не совсем понимаю работу.
1. мы вызываем prepareHorsesAndStart() (создаем список из лошадей, заполняем его и заставляем каждую по очередно бежать. * (тут начинются 10 нитей)
2. зачем в main() нам пустой цикл
while (calculateHorsesFinished(horses) != horseCount) {} ?? ??
3. походу он (пункт н.2) каким то образом запускает calculateHorsesFinished(horses).
Метод этот calculateHorsesFinished(horses) вызывает главная нить main(), так??
4. в этом методе мы берем каждую лошадь "e" из списка лошадей и смотрим, если она финишировала.
5. если нет, то мы делаем e.join(). Главная нить ждет, пока эта лошадь добежит.
6. Как видите после e.join() не стоит finishedCount += 1; а значит, когда лошадь, которую мы ждем добежит, то наша главная (наверное) нить продолжает работать не с места e.join() , а с начала , с if (e.isFinished()){ ___ ПОЧЕМУ??????
вот этот метод:
public static int calculateHorsesFinished(List<Horse> horses) throws InterruptedException {
int finishedCount = 0;
for (Horse e: horses ){
if (e.isFinished()){
finishedCount += 1;
}
else {
System.out.println ( "Waiting for " + e.getName());
e.join();
}
}
return finishedCount;
}
0
IceBergMaster
10 февраля 2019, 00:48
Попытаюсь объяснить в рамках своих знаний.
- метод main основная нить, она вызывает prepareHorsesAndStart() который создает и стартует ещё 10 нитей, с этого момента у нас 11 нитей работают независимо.
- сразу после этого main запускает цикл "while (calculateHorsesFinished(horses) != horseCount)" в котором, происходит задержка метода main пока не финишируют все 10 лошадей, т.е. бесконечно вызывается метод "calculateHorsesFinished(horses)" пока он не вернет значение 10 равное hourseCount.
- в самом методе берётся лошадь, и если она ещё не финишировала "e.isFinished()" мы её ждем вызывая метод "join()", в этот момент остальные лошади бегут вместе с этой лошадью, но мы ждем одну. Когда метод "join()" отрабатывает, сама лошадь в своем методе "run()" устанавливает значение "isFinished = true". Метод "calculateHorsesFinished(horses)" возвращает значение "finishedCount = 0" так как мы ждали первую лошадь, и не успели инкриминировать значение "finishedCount". Потом в цикле "while (calculateHorsesFinished(horses) != horseCount)", метод запускается повторно, теперь уже, как минимум, первая лошадь уже финишировала "isFinished = true", а скорее всего несколько других лошадей уже тоже успели финишировать (пока мы ждали 1-ю), а значит значение "finishedCount" будет несколько раз увеличено после прочерки "e.isFinished()" (другие лошади сами установили значение своей переменной "isFinished = true"), но есть еще лошади, которые не финишировали, поэтому, берем такую лошадь, и ждем её "join()". После возвращаем "finishedCount", если он ещё не равен 10, значит снова запускается цикл по кругу, и ждем, снова и снова, пока в метод "calculateHorsesFinished(horses)" все лошади не будут иметь "isFinished = true", в таком случае мы инкриминируем finishedCount десять раз, и метод вернет значение 10 равное hourseCount, и цикл "while (calculateHorsesFinished(horses) != horseCount)" завершиться, т.е. основная нить main завершает свою работу убедившись, что остальные нити закончили свою.
+2
IceBergMaster
10 февраля 2019, 00:48
По сути, переменная isFinished сигнализирует, что нить завершилась, а метод main, возвращая значение calculateHorsesFinished(horses) проверяет, все ли нити завершили работу.
- prepareHorsesAndStart() - создаем 10 нитей.
- while (calculateHorsesFinished(horses) != horseCount) - ждем 10 нитей.
- calculateHorsesFinished(horses) - проверяем и ждем 1 рандомную нить, можно сократить до результат, по сути, будет тот же, просто без ожидания рандомной нити, метод будет вызван больше раз, пока он не вернет 10.
"6. Как видите после e.join() не стоит finishedCount += 1; а значит, когда лошадь, которую мы ждем добежит, то наша главная (наверное) нить продолжает работать не с места e.join() , а с начала , с if (e.isFinished()){ ___ ПОЧЕМУ?????? "
Да, так и есть, даже если последняя лошадь финиширует в "e.join()" значение будет "9", и нам придется запустить метод ещё раз, что-бы получить "10", но это не проблема, так как while будет вызывать метод, пока он не вернет "10".
+2
Dima
10 февраля 2019, 13:09
Большое спасибо за обьяснение! Не знал, что условие цикла может быть и его телом.
while (calculateHorsesFinished(horses) != horseCount) {
}
Теперь буду знать что и так можно) Спасибо.
И я также понял кто кого ждет. Наша главная нить main и ждет)
0