Определяем порядок захвата монитора

  • 14
  • Недоступна
Реализуй логику метода isLockOrderNormal, который должен определять: соответствует ли порядок synchronized блоков в методе someMethodWithSynchronizedBlocks - порядку передаваемых в него аргументов. В случае, если сначала происходит синхронизация по o1, а потом по o2, метод должен вернуть true. Если
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (101)
  • популярные
  • новые
  • старые
Для того, что бы оставить комментарий вы должны авторизоваться
Джонни35 уровень
8 января, 09:31
Задача называется: Пишем свой валидатор.
Vitaly Khan35 уровень
7 января, 12:48
знатная головоломка... долго с ней просидел. аж три sleep пришлось использовать, чтобы результат был корректный всегда. первый: между запусками двух вспомогательных нитей, например, 50 мс. чтобы первая (с нашим порядком локов) гарантированно запускалась раньше. второй: внутри первой нити, чтобы после захвата первого лока нить гарантированно уступала ход второй нити. здесь ожидание должно быть обязательно более 50 мс. я ставил 100. третий: в основной нити, чтобы точно дать возможность выполниться вспомогательным нитям (если у них нет дедлока). также, на мой взгляд, корректно вспомогательные нити делать демонами (чтобы при дедлоке программа тоже завершалась). но валидатор этого не требует.
Ruslan28 уровень
18 декабря 2018, 20:13
Вы решили задачу лучше, чем 1% учеников. Вам удалось ее решить с 48 попытки. Среднее количество попыток для этой задачи 4.53. Всего эту задачу решили 3269 учеников. //:
Serj41 уровень, Киев
9 ноября 2018, 01:27
решил через 3 нити, валли принял: -основная нить блокирует о1 -2я нить запускает someMethodWithSynchronizedBlocks -3я нить пытается заблокировать о2 в основной нити выводим состояние 3й нити
Евгений29 уровень, Москва
11 января, 17:30
Спасибо огромное! До этого пытался допинать способ с двумя нитями, он работал корректно, но для true выводил еще System.out.println( obj1 + " " + obj2 ); А этот вариант вообще огонь - с первого раза без всяких танцев с бубном и лишнего вывода на экран.
Ilya Sakharov41 уровень, Москва
2 октября 2018, 15:37
От себя тоже добавлю подсказку. От вас ожидают, что в методе isNormalLockOrder вы создадите две нити и сделаете deadlock в точности как в предыдущих задачах. В одной нити делаете тотже порядок synchronized, как в someMethodWithSynchronizedBlocks, во второй вызываете сам метод someMethodWithSynchronizedBlocks. Если порядок блокировки в someMethodWithSynchronizedBlocks правильный (т.е. сначала o1, потом o2), как в вашей первой нити, то deadlock'a не произойдет и в isNormalLockOrder надо вернуть true. Если deadlock случился, то возвращаем false. Проверить на наличие dedadlock можно после небольшого sleep простым условием if([одна из нитей].getState() == Thread.State.BLOCKED). Ну и всё.
Михаил Голубцов41 уровень, Санкт-Петербург
16 октября 2018, 18:55
Спасибо за подсказку, я никак не думал что от меня ожидают сделать deadlock. Добавлю только, что у обоих нитей можно перед стартом вызвать .setDaemon(true) чтобы программа не зависала. --- Пока копался вспомнил про wait() / notify() а так же узнал про пакет java.util.concurrent.locks
Сережа Шишкин27 уровень, Los Angeles
26 сентября 2018, 10:15
Долго разбирался с этой задачей, но зато в итоге познал истину) Помог разобраться комментарий Сергея за 23 августа, 15:24. Что я в начале делал не так: Я пытался в методе isNormalLockOrder сделать 2 нити чтобы они между собой начали блокировать объекты так, чтобы вышел дедлок, это не совсем корректно. Что надо было сделать в итоге: В методе isNormalLockOrder в одной нити корректно заблокировать объекты так, чтобы при вызове метода someMethodWithSynchronizedBlocks из 2й нити произошел дедлок из-за блокировок объектов именно в методе someMethodWithSynchronizedBlocks ! Т.е. дедлок происходит из-за одновременной перекрестной блокировки объектов из 2х методов!
Mark34 уровень, Санкт-Петербург
13 сентября 2018, 18:54
Решилось в три нитки зато сразу: Нитка #1 запускается, лочит obj1 и засыпает. Делаем небольшую паузу, чтобы первая нитка гарантированно отработала свою задачу. Город засыпает, просыпается мафия вторая нитка кродется с проверяемым методом и двумя объектами синхронизации, и пытается их залочить. Дальше два варианта: - первый объект у нее тот же obj1, она в него упирается и ничего не делает - первый объект у нее obj2, она его лочит и только потом упирается в obj1. В результате имеем obj1 гарантированно залочен еще первой ниткой, а вот obj2 может быть как занят так и свободен, в зависимости от очередности в тестируемом методе. Это и предстоит проверить ните #3. Она запускается и что-то делает синхронизируясь по obj2. Если obj2 свободен - то это действие произойдет сразу. Если занят - ей придется дождаться пока первая нить проснется, освободит obj1, потом нить #2 сможет сделать свои дела на обоих объектах, и уж потом выполнится блок syncronized нити #3. Проверив очередность выполнения мы узнаем в каком состоянии был obj2 к подходу третий нити, а значит очередность блокировки у нити с тестируемым методом.
Yurii Koval40 уровень
3 сентября 2018, 19:20
Задача бредовая. Сразу смотрите в комментарии где и сколько надо спать, ибо валя не будет принимать.
fanar630 уровень, Москва
31 августа 2018, 12:38
12 попытка (8%), не рекорд местный, но тем не менее. Задача интересная, на самом деле. Но условие не понятное, а многие комментаторы, мне кажется, не вкурили, что они вообще решили... Как был пример с Math.Random() где-то ниже ) Хотел бы оставить здесь свое объяснение к постановке задачи. Может быть кому-то пригодится для понимания (надеюсь, я правильно понял цель): Итак, у нас есть класс Solution, в нем два метода isNormalLockOrder, someMethodWithSynchronizedBlocks. В чем может быть проблема? Кто-нибудь, наследовавшись от нашего класса, изменил метод someMethodWithSynchronizedBlocks, так, чтоб сначала лочился o2, а потом o1, и везде подсовывает объект вместо Solution --> SolutionWithChange extends Solution (видимо, try-хацкер хочет сломать наш код и загнать его в DeadLock). Предвидя это "уязвимое" место, мы пытаемся ему помешать. И прежде, чем вызывать метод someMethodWithSynchronizedBlocks мы должны проверить, а не накроется ли все медным тазиком? Для этого вызываем метод isNormalLockOrder. Если он возвращает true, значит, все пройдет успешно, если false - ищем нерадивого программиста или try-хацкера - в любом случае беспощадно наказываем. ИТОГ: суть задачи заключается в том, что метод isNormalLockOrder должен проверить работоспособность метода someMethodWithSynchronizedBlocks - в конкретном ОБЪЕКТЕ solution, передаваемого в метод.
Сергей35 уровень, Одесса
23 августа 2018, 14:24
Удалось сваять по комменту, взятому с обсуждения (ниже) : Все оказалось просто. Создаем 2 нити. В первой создаем synchronized по о1, потом слип на 500 мс, внутри ставим второй synchronized по о2. Во второй нити просто вызываем someMethodWithSynchronizedBlocks(o1, o2); запускаем первую нить, запускаем вторую нить и ставим на паузу на 2 секунды. Проверяем состояние второй нити: если НЕ blocked - возвращаем тру, иначе фолс. Логика такова. Мы специально создаем дедлок. Если в даном нам методе синхронизация происходит сначала по 1 объекту, потом по 2, значит дедлока не будет и наш метод просто подождет немного и выполнится, иначе образуется дедлок и вторая нить станет BLOCKED. Надеюсь понятно объяснил) Прокатал проверку несколько раз (для надежности). Принимает. Пока это самое толково объясненное решение, которое нашел
Максим27 уровень, Москва
10 октября 2018, 17:38
Гуд ! Спасибо
Airat35 уровень, Уфа
11 октября 2018, 10:18
Спасибо большое, кстати первая нить тоже станет BLOCKED, проверку можно проходить и на ней
Lex35 уровень, Минск
29 октября 2018, 19:59
Спасибо
Di30 уровень, Москва
15 января, 22:45
"В первой создаем synchronized по о1, потом слип на 500 мс, внутри ставим второй synchronized по о2. " - а для чего здесь слип?