ясно, что метод, реализованный Sun, не просто возвращает время указанному потоку, но фактически сначала пытается получить монитор объекта потока.
Он не уступает присоединенному потоку, он просто ожидает с предположением, что в какой-то момент поток будет завершен. Наличие join () в потоке не повышает его вероятность выполнения по сравнению с любым другим потоком, готовым к запуску.
- Если все N потоков пытаются присоединиться к одному и тому же потоку, и все они указывают одинаковое время ожидания T, то один из потоков в конечном итоге ожидает не менее N * T мс. Другими словами, каждый поток должен «ждать своей очереди», чтобы выполнить свое ожидание. Разумно ли для отдельных потоков выполнять соединения последовательно, а не параллельно?
Потоки предназначены для одновременной работы. Если они все ждут, они делают это одновременно. Ожидающий поток не заставляет другой поток ждать дольше.
0,2. Возможно, что поток, который входит в соединение с ненулевым таймаутом, может никогда не вернуться.
нет, если только вы не собираетесь это сделать.
Это потому, что нет гарантии, что монитор когда-либо станет доступным.
Ситуация, которую вы предлагаете, может возникнуть, только если поток получает блокировку для потока и затем удерживает ее навсегда, не ожидая. Это ошибка программирования. ИМХО Никогда нельзя получать блокировку на объект потока напрямую.
Если поток получает свой собственный монитор перед блокировкой операции ввода-вывода и эта операция зависает, то любой поток, который пытается присоединиться к потоку, также будет зависать.
Java не защищает вас от вредоносного кода в вашей собственной JVM.
Разумно ли для операции с явным временем ожидания зависать бесконечно?
Если он заблокирован на неопределенный срок, да.
0,3. Чтобы написать правильную программу, которая использует метод, вызывающая сторона должна заранее знать, может ли целевой поток или какой-либо другой поток держать монитор.
Никогда не блокируйте объект потока, нет необходимости в этом, и у вас не будет этой проблемы. Если вы хотите начать смотреть на все так, как могли бы сбить с толку других разработчиков или себя, то «Потоки» - не то место, где вы бы начали ИМХО.
Например, рассмотрим, что происходит, если поток 1 выполняет какую-то обработку, затем поток 2 присоединяется к потоку 1 с тайм-аутом 0, а затем поток 3 пытается присоединиться к потоку 1 с тайм-аутом 10 мс. Соединение с тайм-аутом 0 означает, что поток 2 будет ожидать выхода из потока 1. Но поток 3 не может начать свое ожидание, пока поток 2 не освободит монитор,
Поток 2 освобождает монитор, как только вызывается ожидание. Он не может ждать и удерживать монитор одновременно.
так эффективно ожидание потока 3, равное 10 мс, было тихо преобразовано в неопределенное ожидание, что не было тем, что предполагал вызывающий.
нет. см. предыдущие комментарии.
Не требует ли вызывающая сторона знать детали о реализации, нарушающей принцип инкапсуляции?
Было бы.
0,4. Если поток заблокирован из-за того, что он не может получить монитор, он не прервется и не сгенерирует исключение InterruptedException, как описано в документации. Таким образом, поток может не только ждать дольше, чем ожидалось, либо даже неопределенно долго, он может полностью перестать отвечать, что приведет к зависанию всей программы. Разумно ли, чтобы прерываемая операция перестала отвечать на запросы?
да. Но это очень редкое состояние. Если вы используете код в том виде, в котором он написан, ситуация, на которую вы ссылаетесь, будет существовать не более нескольких миллисекунд.
В целом, кажется неуместным делать операцию тайм-аута зависимой от получения монитора, если только не может быть гарантировано, что сама задача получения монитора истечет. Прервано ли соединение?
Вы можете делать то, что предлагаете, с более поздними библиотеками параллелизма Java 5.
Однако я предлагаю вам не предполагать, что тайм-ауты гарантированно будут с точностью до миллисекунды. currentTimeMillis (), используемый этим методом, является точным в Windows XP только до 16 мс, а время ожидания / сна обычно на 2 мс больше, чем должно быть для небольших тайм-аутов в Linux.
ИМХО. Если вам нужна точность более 40 мс, у вас могут возникнуть трудности, однако, если обойти это, вы обнаружите, что это не должно быть проблемой.