Доброго времени суток! Меня давно мучает вопрос: как корректно дебажить многопоточные приложения? Эта задача заставила вновь засесть за изучение документации, однако вопрос остался не решенным. Ниже полезная информация, которую нашел во время изучения вопроса: (сам вопрос по задаче находится в выделенной области ниже) 1) Если в задаче имеются несколько нитей, а breakpoint в run'e только одной нити, то во время дебаггинга этой нити,остальные будут исполнятся вне зависимости от того, хотим мы этого или нет. Чтобы продебажить одну нить от "А до Я", однако при этом важно, чтобы остальные нити не исполнялись, есть функция: Settings -> Build, Execution, Deployment -> Debugger -> Stepping -> (установить галку) Resume only current thread 2) Свойства точки останова: Если в свойствах (Ctrl + Shift + F8) выбрать для точки останова в поле Suspend чекбокс All, то идеей это воспринимается, как "остановка любой нити, которая пришла в этот breakpoint", если же выбрать в чекбоксе Thread, то остановится только та нить, внутри которой находится эта точка останова. Причем в хэлпе на сайте идеи написано следующее: "The program will not be suspended at a breakpoint if its policy is set to All, and some actions stepping actions are performed when this breakpoint is hit.", то есть в режиме ALL "при достижении этой точки останова, будет остановлена та нить, которая дошла до этой точки, остальные же нити во время дальнейшего дебаггинга продолжат работать в фоновом режиме (делаем следующий шаг в дебаггере, в фоне работают другие нити (насколько я понимаю, им может быть выделен квант времени, а может и больше (как решит планировщик) (если ошибаюсь, пожалуйста, поправьте) Если же в свойствах точки выбран тип останова Thread, то как только нить, которой принадлежит этот breakpoint достигнет его, она будет тут же приостановлена. (это проверяется через окно Frames при переключении между "снимками" стэка.) 3) Панель Frames и Threads Эти инструменты позволяют переключаться между нитями во время дебаггинга программы, в панели Frames, как уже сказал выше находятся все нити, которые запущены на данный момент, с помощью этого инструмента можно переключаться между этими нитями и видеть, на каком этапе выполнения находится нить (если она не приостановлена Suspend, если приостановлена то при последующих переключениях на эту нить, не будет происходить выполнения кода этой нити) В панели Threads можно просмотреть весь стек вызовов (весь жизненный цикл нити на текущий момент), причем, если в панели Frames установить текущей какую-либо нить, в окне Threads эта нить будет располагаться отмеченной соответствующим значком в самом верху списка. 4) Панель Parallel Stacks Об этой панели написано вот в этой статье. Этот инструмент позволяет графически отобразить ход выполнения многопоточной программы. Также об этом инструменте написано в описании окна Debug на сайте идеи. Однако, мне этот инструмент в панели дебаггера найти не удалось. Если кто-то знает, как включить это окно, напишите, пожалуйста. ================================================================================================= А теперь для тех, кто дочитал мой основной вопрос: ================================================================================================= Во время дебаггинга этой программы столкнулся с таким парадоксом: ставлю breakpoint на первую и вторую нить (для первой нити - строка вызова метода moveMoney(), для второй нити - строка проверки изменения баланса в цикле). Я так понимаю, когда мы вставляем в метод moveMoney() команду Thread.yield(), то нить должна, точнее "рекомендует" передать управление другой нити. В таком случае, хоть иногда, но нить должна передавать управление другой нити, не завершив свой квант времени. Однако, что получаем в действительности: куда ты не ставь Thread.yield(), управление не передается (проверено в режиме дебагга несколько десятков раз). Может я чего не понимаю, но даже в случае установки в метод moveMoney() в любом месте Thread.sleep(1000), "шагая по коду", я не попадаю во вторую нить. Переключиться на нее в панели Frames я могу, а вот попасть "шагая по коду первой нити" нет. Так понимаю, при достижении строки Thread.sleep(1000) в методе moveMoney(), дебаггер должен меня перебрасывать в другую нить, поскольку управление передается именно ей, но этого не происходит. Я в коде свободно "прошагиваю" строку со sleep() и иду дальше. Подскажите, пожалуйста, что я не так делаю? Также иногда замечал, что что программа переключается на точку останова в другой нити, но не останавливается на ней и снова возвращает меня к первой нити. Буду очень благодарен за обратную связь!