Horse Racing

  • 18
  • Недоступна
Уж лучше программировать, чем делать ставки... Тем не менее, скачки и прочие гонки прекрасно иллюстрируют многопоточность! Итак, разберитесь, что делает код, и реализуйте метод, который будет считать количество лошадей, пришедших к финишу. И ещё, нужно обязательно подождать, пока аутсайдеры также закончат гонку.
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (568)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Roman
Уровень 19
2 сентября, 08:30
Всем привет. Кто подскажет какова механика выполнения очередности процессов (нитей) ? То есть мы запустили 10 параллельных процессов, причем первый стартовал первым, а десятый десятым, значит логично, что первый закончит первым, а десятый десятым, если только процессор компьютера не начнет скакать с одной нити на другую в рандомном порядке. Поэтому не понятно в соответствии с какой логикой процессор компьютера переключается на выполнение той или иной нити. Чем это определяется?
Serg
Уровень 33, Санкт-Петербург
18 сентября, 13:47
Там совершенный рандом, как JVM торкнет так и будет запускать, попробуйте позапускать в IDEJ - увидите что при каждом запуске очередность может быть разная. без join() невозможно предугадать в каком порядке будут выполняться нити. Собственно это и есть фишка псевдомногопоточности, когда ты прыгаешь из одной нити в другую и выполняешь в каждой по чуть чуть. Попробуйте в каждой нити написать много операторов с выводом, увидите как каждый раз все будет путаться.
Roman
Уровень 19
19 сентября, 15:00
спасибо
smart_engineer
Уровень 27, Россия
31 августа, 19:02
После завершения работы программы, консоль должна содержать информацию о том, что все лошади финишировали. Пример сообщения для первой лошади: "Horse_01 has finished the race!". Возможно правильно бы было требовать "All horses finished the race!" Сбивает с толку этот пункт. Он вроде как автоматом выполняется. P.S. Слишком просто для сложной задачи.
Рустам
Уровень 19, Екатеринбург, Россия
13 августа, 03:30
Для тех, у кого проблемы с пунктом 1. У меня долгое время не принимался этот пункт.
Было:
фор (Horse х : horses)...
и дальше все через "х"...
Поменял на:
фор (Horse horse : horses)...и переменные через "horse"...
...
иии...все заработало!!!😐
Виктор Волошин
Уровень 19, Москва, Россия
16 августа, 07:43
Просто какая-то странность при валидации этой задачи. Код у Вас по сути не поменялся, просто валя сработал со второго раза. Как и у меня🤷‍♂️ я вообще в итоге код не поменял, а он бац! и принял. Чудеса...
Святослав
Уровень 17, Одесса
9 сентября, 15:09
Потому что мы по условию выводим System.out.println("Waiting for " + horse.getName()); а не System.out.println("Waiting for " + x.getName());
Alexander G.
Уровень 22, Москва, Россия
3 августа, 18:49
почему-то такую конструкцию принимает
if (horse.isFinished()) {
                finishedCount++;
            } else {
                System.out.println("Waiting for " + horse.getName());
А такую нет
if (!horse.isFinished()) {
              .......
              .....
          }
          finishedCount++;
А главное, зачем валидатор говорит, что ошибка в первом пункте: "Метод calculateHorsesFinished должен вернуть количество финишировавших лошадей." Нет ну это вообще не правда! Метод прекрасно возвращает положенное! Это первая задача, которую я решил за 9 попыток :(
Павел
Уровень 19
23 июля, 11:52
тяжело понять что от тебя хотят ! я думал что те лошади которые "Waiting for " + horse.getName() недолжны закончить гонку вообще! но это не так 2 дня сидел( оказывается все два дня было правильное решение ,просто лишнего написывал! P.S. просто крик души
Андрей Захаренков
Уровень 20, Санкт-Петербург
18 июля, 08:50
У нас есть 10 лошадей, подготовленных к старту. Метод main обращается к calculateHorsesFinished пока все 10 не финишируют. В классе Horse создается новая нить. Метод run() переопределен так, что лошадь финиширует с задержкой 1000. В этом и кроется рандом пришедших первыми лошадей т.к. потоки переключаются между друг-другом и кто-то "вырывается вперед". Если нет - поправьте. И когда это происходит, в boolean isFinished записывается значение true — это мы и будем проверять через вызов метода isFinished() Проверка того, кто финишировал, проводится в методе calculateHorsesFinished Через цикл for проходимся по List<Horse> Если лошадь.финишировала() — finishedCount++ Если нет — "Waiting for " + horse.getName() и ждем её поток.
Руслан
Уровень 23, Стерлитамак, Россия
9 июля, 18:06
Не понятно на половину условие задачи почему-то
Данил Семёнов
Уровень 32, Санкт-Петербург
7 июля, 10:43
у меня такой вопрос почему после вывода в консоль строки "Waiting for Horse_01" следующая строка не "Horse_01 has finished the race!"
All horses start the race!
Waiting for Horse_01
Horse_10 has finished the race!
Horse_05 has finished the race!
Horse_08 has finished the race!
Horse_03 has finished the race!
Horse_02 has finished the race!
Horse_09 has finished the race!
Horse_06 has finished the race!
Horse_01 has finished the race!
Waiting for Horse_04
Horse_07 has finished the race!
Horse_04 has finished the race!
ведь командой join(), мы дожидаемся пока завершится нить лошади под номером один, а уже после ее завершения приступаем к остальным нитям. А вывод в консоль говорит об обратном так как последняя команда метода run первой лошади это "Horse_01 has finished the race!"
Галкин Юрий
Уровень 25, Москва
17 июля, 11:59
Будто есть ещё отдельная реальность стопки (стэка) завершения. Можно проверить есть ли в ней процесс, и если если нет, то вот тогда дождаться завершения этого процесса, и тогда добавить его. И потом исполнить всю стопку. Очевидно стопка исполняется в порядке LIFO, как раз обратном от порядка попадания.
Seroygin
Уровень 26, Тернополь, Украина
14 августа, 13:47
Потому что в консоль об окончании забега выводит не основная нить программы, которая ждёт окончания забега лошади, а финишировавшая лошадь. Все лошади бегут параллельно независимо от основной программы, и та что закончила забег говорит что она уже всё, в то время как основная программа дожидается другую лошадь.
Сергей
Уровень 34, Кандалакша, Россия
7 октября, 12:16
Все правильно, мы ждем, пока не финиширует первая лошадь, после чего продолжаем идти по циклу foreach, проверяем второю, треть и т.д, а в это время (пока мы проверяем) финишируют и другие лошади .Вот в выводе видно, что мы дождались финиша первой лошади, а пока дошли до проверки третьей - успела финишировать 10: Waiting for Horse_01 Horse_09 has finished the race! Horse_07 has finished the race! Horse_08 has finished the race! Horse_05 has finished the race! Horse_06 has finished the race! Horse_04 has finished the race! Horse_02 has finished the race! Horse_01 has finished the race! Horse_10 has finished the race! Waiting for Horse_03 Horse_03 has finished the race!
Maksym QA Automation Engineer
2 июля, 16:12
у меня получилось решение в один, как эталонное, но порой вот так выскакивало:
Horse_03 has finished the race!
Waiting for Horse_03
Павел Кекух Разливайка в Розливуха
9 августа, 19:36
Как я понимаю, в блоке кода
1. System.out.println("Waiting for " + horse.getName());
 2. horse.join();
завершение 2-го пункта может иногда происходить немного быстрее, чем вызов метода из пункта 1 (с параметрами), даже если робот обратился к 1-ому раньше. Не панацея, но можно дать поспать какое-то время. Текущей проблемы более не возникает.
1. System.out.println("Waiting for " + horse.getName());
2. Thread.sleep(1000);
3. horse.join();
Как я понял посыл этой задачи - "Семеро одного не ждут"
Андрей
Уровень 37, Москва, Россия
29 июня, 10:26
Ключевая фраза в условии задачи:
2.2. Подождать, пока она завершит гонку. Подумай, какой метод нужно использовать для этого.
2.3. Не считать такую лошадь финишировавшей.
Есть соблазн увеличить счетчик после того как нашли не финишировавшую лошадь и дождались когда она финишировала, но это не правильно. Счетчик нужно увеличивать только когда isFinished() == true
IL
Уровень 31, Москва, Россия
29 июня, 16:24
помог с решением👍
Torba Z Dimom
Уровень 23, Киев, Украина
29 июля, 13:07
Годное замечание!
Stepan
Уровень 17, Киев
5 августа, 14:42
Хороший комментарий. Я пришел к этому решению сам, но это был последний баг над которым я посидел.