Лекции 2025. Java. Белая / Ответы на билеты. Java
.pdf
Значение
:
Если
равен
(и
тоже
), это эквивалентно вызову
без параметров (бесконечное ожидание).
Если |
отрицательный, будет выброшено |
. |
||
Сводка отличий: |
|
|
|
|
|
|
|
|
|
Характеристика |
|
(без таймаута) |
(с таймаутом) |
|
|
|
|
|
|
|
|
|
|
|
Состояние потока |
|
|
|
|
|
|
|
|
|
Длительность |
Неограниченно (до |
Ограничено указанным |
|
|
ожидания |
, |
или |
(или другими событиями) |
|
|
ложного пробуждения) |
|
|
|
|
|
|
|
|
Пробуждение по |
Нет |
|
Да, если таймаут истекает до |
|
времени |
|
|
других событий |
|
|
|
|
|
|
Основное |
Ожидание условия без |
Ожидание условия с |
|
|
применение |
ограничения по времени |
ограничением по времени, |
|
|
|
|
|
предотвращение бесконечного |
|
|
|
|
ожидания |
|
|
|
|
|
|
Когда использовать
с таймаутом:
Чтобы избежать ситуации, когда поток ждет бесконечно, если уведомление по какой-то причине не приходит (например, из-за ошибки в логике другого потока). Когда нужно периодически проверять какое-то состояние или выполнять другие действия, если условие не выполняется в течение определенного времени. Для реализации операций с таймаутом (например, попытка получить ресурс в течение X секунд).
Пример:
В этом примере потребитель ждет данные не более 3 секунд. Если производитель установит
и вызовет
раньше, потребитель пробудится. Если 3 секунды истекут раньше, потребитель пробудится по таймауту.
70. Чем отличаются методы Thread.sleep() и Thread.yield()?
Методы
и
оба являются статическими методами класса
и используются для влияния на планирование потоков, но они служат разным целям и имеют разное поведение.
(и
)
Назначение: Приостанавливает выполнение текущего потока на указанный период времени (в миллисекундах или миллисекундах + наносекундах). Состояние потока: Переводит текущий поток в состояние
.
Освобождение мониторов: Не освобождает никакие мониторы (блокировки),
которыми владеет текущий поток. Если поток находится в
блоке/ методе и вызывает
, он продолжает удерживать монитор, что может привести к блокировке других потоков, ожидающих этот монитор.
Гарантия времени: Гарантирует, что поток не будет выполняться как минимум указанное время (если не будет прерван). Фактическое время приостановки может быть немного больше из-за особенностей системного таймера и планировщика. Прерывание: Если другой поток вызывает
на спящем потоке, метод
немедленно завершается, выбрасывая
. Флаг прерывания текущего потока при этом сбрасывается.
Использование:
Для создания пауз в выполнении потока.
Для имитации задержек или периодического выполнения задач (хотя для сложных периодических задач лучше использовать
).
В некоторых случаях для уменьшения загрузки CPU, давая другим потокам шанс выполниться (хотя
может быть более подходящим для этой конкретной цели, если пауза не нужна).
Назначение: Это подсказка (hint) планировщику потоков о том, что текущий поток
готов уступить свое текущее использование процессора другим потокам с таким же или более высоким приоритетом, которые готовы к выполнению. Состояние потока: Если
имеет эффект, текущий поток может временно перейти из состояния "выполняемый" (running) в состояние "готовый" (ready) в рамках общего состояния
. Он не переходит в
,
или
.
Освобождение мониторов: Не освобождает никакие мониторы (блокировки),
которыми владеет текущий поток.
Гарантия времени: Не дает никаких гарантий. Планировщик потоков может полностью проигнорировать эту подсказку. Если нет других потоков, готовых к выполнению, или если планировщик решит иначе, текущий поток может немедленно продолжить свое выполнение.
Прерывание: Метод
не выбрасывает
.
Использование:
Редко используется в современном Java-программировании, так как его поведение сильно зависит от реализации JVM и операционной системы, и на него нельзя полагаться для точной синхронизации или управления производительностью.
Теоретически мог бы использоваться в очень загруженных системах для попытки дать другим потокам шанс выполниться, особенно в задачах с активным ожиданием (busy-waiting), чтобы избежать полного захвата CPU одним потоком. Однако, обычно есть лучшие способы решения таких проблем (например, использование
, блокировок, или более подходящих синхронизаторов).
Сводка отличий:
Характеристика |
|
|
|
|
|
Основное действие |
Приостанавливает поток |
Предлагает планировщику |
|
на заданное время. |
переключиться на другой |
|
|
готовый поток. |
|
|
|
Характеристика |
|
|
|
|
|
|
|
Состояние потока |
|
Остается |
(может |
|
|
перейти из "running" в |
|
|
|
"ready"). |
|
|
|
|
|
Освобождение |
Нет. |
Нет. |
|
мониторов |
|
|
|
|
|
|
|
Гарантия эффекта |
Да (поток будет спать как |
Нет (планировщик может |
|
|
минимум указанное |
проигнорировать). |
|
|
время). |
|
|
|
|
|
|
Время приостановки |
Заданное (миллисекунды). |
Неопределенное (если |
|
|
|
эффект есть, то на очень |
|
|
|
короткое время, до |
|
|
|
следующего кванта). |
|
|
|
|
|
|
Да (может быть |
Нет. |
|
|
выброшено, если поток |
|
|
|
прерван во время сна). |
|
|
|
|
|
|
Типичное применение |
Создание пауз, задержек. |
Редко используется; |
|
|
|
теоретически для |
|
|
|
улучшения отзывчивости в |
|
|
|
некоторых сценариях. |
|
|
|
|
|
Пример: |
|
|
|
В этом примере
будет делать заметные паузы. Поведение 
и
будет менее предсказуемым;
может (или не может) привести к тому, что они будут чаще уступать друг другу процессор, особенно если система не сильно загружена.
Вывод:
— это надежный способ приостановить поток на определенное время.
— это гораздо менее надежный механизм, на который не следует полагаться для критически важной логики синхронизации или управления производительностью. В большинстве случаев, если вам нужно координировать потоки, лучше использовать более явные механизмы синхронизации (
,
, синхронизаторы из
).
71. Как работает метод Thread.join()?
Метод
класса
используется для того, чтобы один поток мог дождаться завершения другого потока. Когда поток
вызывает
,
поток
приостанавливает свое выполнение (переходит в состояние
или
) до тех пор, пока поток
не завершит свое выполнение (т.е. его
метод
не закончит работу).
Основные характеристики и поведение
:
1.Назначение: Обеспечивает упорядочивание выполнения потоков, позволяя одному потоку дождаться результатов или завершения работы другого.
2.Блокировка вызывающего потока: Поток, который вызывает
,
блокируется до тех пор, пока поток, на котором вызван
, не умрет (станет
).
3. Перегруженные версии:
: Ожидает завершения потока неопределенно долго.
: Ожидает завершения потока не более указанного количества миллисекунд. Если поток не завершился за это время, вызывающий
поток возобновит свое выполнение.
: Ожидает с точностью до наносекунд.
4.
: Если текущий поток (который вызвал
и ожидает) прерывается (
) другим потоком во время ожидания, метод
выбросит
. Флаг прерывания при этом сбрасывается.
5. Состояние потока:
Поток, на котором вызван
(целевой поток), продолжает свое нормальное выполнение.
Поток, который вызвал
(ожидающий поток), переходит в состояние
(для
) или
(для
).
6.Вызов на уже завершенном потоке: Если
вызывается на потоке, который уже завершился, он немедленно возвращает управление, и вызывающий поток не блокируется.
7.Вызов
на самом себе: Вызов
приведет к взаимной блокировке (deadlock), так как поток будет ждать сам себя, что невозможно. (Хотя спецификация говорит, что поведение в этом случае не определено, на практике это обычно deadlock).
Как это работает "под капотом" (упрощенно):
Метод
обычно реализуется с использованием механизма
. Когда поток A вызывает
, поток A входит в цикл, который проверяет, жив ли еще
(
). Если жив, поток A вызывает
(или
) на объекте
. Когда
завершается, он неявно (или явно, в зависимости от реализации JVM) вызывает
на своем собственном объекте
, что пробуждает все потоки, ожидающие его завершения через
.
Пример использования:
Сценарии использования
:
Последовательное выполнение задач: Когда результат одной задачи
(выполняемой в потоке) необходим для начала другой задачи (в другом потоке или в основном потоке).
Ожидание завершения всех рабочих потоков: Основной поток может запустить несколько рабочих потоков и затем использовать
на каждом из них, чтобы дождаться, пока все они не закончат свою работу, прежде чем продолжить (например, для агрегации результатов или закрытия ресурсов).
Обеспечение порядка: Гарантировать, что определенные действия произойдут только после завершения других.
Важно:
Чрезмерное использование
может привести к снижению параллелизма, так как потоки будут простаивать в ожидании.
Всегда обрабатывайте
, так как ожидание через
может быть прервано.
Метод
является важным инструментом для координации потоков и управления их последовательностью выполнения в Java.
72. Исключения. Обработка исключительных ситуаций.
Исключения (Exceptions) в Java — это события, которые возникают во время выполнения программы и нарушают ее нормальный ход. Они сигнализируют об ошибках или нештатных ситуациях. Java предоставляет мощный механизм для обработки исключений, позволяющий программе корректно реагировать на ошибки, а не аварийно завершаться.
Иерархия исключений:
Все классы исключений в Java наследуются от класса
. Основные ветви иерархии:
1.
:
Представляют серьезные проблемы, от которых приложение обычно не может оправиться.
Чаще всего возникают из-за проблем в среде выполнения JVM (например,
,
,
).
Приложения обычно не должны пытаться ловить (catch)
, так как причина ошибки, как правило, фатальна.
2.
:
Представляют менее серьезные проблемы, от которых приложение может и должно пытаться оправиться.
Делятся на два основных типа:
Проверяемые исключения (Checked Exceptions):
Это исключения, которые компилятор Java требует обрабатывать.
Если метод может выбросить проверяемое исключение (и не обрабатывает его сам), он должен объявить это в своей сигнатуре с помощью ключевого слова
.
Вызывающий код, в свою очередь, должен либо обработать это исключение в блоке
, либо также объявить его в
.
Примеры:
,
,
,
.
Цель: Заставить разработчика подумать об обработке потенциальных ошибок, которые могут возникнуть при взаимодействии с внешними ресурсами или в других предсказуемых проблемных ситуациях.
Непроверяемые исключения (Unchecked Exceptions) / Исключения времени выполнения (Runtime Exceptions):
Это исключения, которые не требуют обязательной обработки
компилятором (хотя их можно ловить).
Они наследуются от
(который, в свою очередь, является подклассом
).
Обычно сигнализируют об ошибках в логике программы (программные ошибки) или непредвиденных ситуациях во время выполнения.
Примеры:
,
,
,
,
(например, деление на ноль).
Объявлять их в
не обязательно, но можно.
Механизм обработки исключений:
Используются ключевые слова
,
,
,
,
.
