Блокировать без раскрутки на Яве?

Некоторые методы в Java будут блокироваться до тех пор, пока они не смогут что-то сделать, например ServerSocket.accept () и InputStream.read (), но мне нелегко понять, как это происходит. Самое близкое, что я могу придумать, - это цикл while () с Thread.sleep () каждый раз, но чем дольше период сна, тем менее чувствительна блокировка и чем короче сон, тем больше происходит вращение.

У меня два вопроса:

  1. Как блокируются различные стандартные функции, подобные приведенным выше? Родной код? while () циклы? Что-то другое?

  2. Как мне реализовать методы, которые блокируют?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
4 965
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Перечисленные вами операции блокируются из-за базовой платформы (т. Е. Собственного кода).

Вы можете реализовать блок, используя методы Java Object.wait() и Object.notify(); wait() будет блокировать вызывающий поток до тех пор, пока другой поток не вызовет notify() с той же блокировкой.

Я могу ответить на часть 1. Они используют ОС, чтобы справиться с этим, поскольку каждая ОС уже имеет встроенную сигнализацию и блокировку как часть обеспечения многозадачности.

Обычно, если вам нужно реализовать свой собственный код вращающейся блокировки, вы либо используете неправильные методы. Вращение также уменьшает любую форму управления питанием, даже при хорошем сне код все равно должен просыпаться, чтобы ничего не делать.

Чтобы ответить (2), вы хотите, чтобы методы объекта ждали, уведомляли и notifyAll.

При использовании Object.wait () вы должны заключить ожидание в цикл, который проверяет условие, по которому вы ждете. Метод wait () может ложно возвращаться (по неявным причинам).

Кроме того, вам нужно подумать о том, нужно ли вам использовать notify () или notifyAll () - если все ожидающие потоки ожидают точно такого же условия, и вам нужен только один для обработки того, о чем вы уведомляете, вы можно использовать notify (), в противном случае вам нужно использовать notifyAll (), поскольку у вас нет гарантий, какой поток будет уведомлен при notify () - вы не можете ожидать, например, что они будут циклическими.

Наконец, не забудьте взглянуть на пакет java.util.concurrent - в нем есть много более высокоуровневых и лучших решений общих проблем с потоками, чем при использовании примитивов Java.

Ответ принят как подходящий

Существенный ответ на (1): «не беспокойтесь об этом - это сделает ОС». Вызовы таких вещей, как чтение из входных потоков, по сути являются оболочками для вызовов операционной системы. Под капотом внутри ОС, я думаю, что обычно происходит, когда вызов "блокируется" в этих случаях, так это то, что ОС "знает", что она ожидает аппаратного прерывания, скажем, от контроллера диска, чтобы сказать, что такое - и -такие запрошенные данные теперь доступны, и он знает, что именно поток X запросил эти данные. Таким образом, он не планирует в потоке X снова, пока он не получит это прерывание (или прерывание с сообщением «произошла ошибка» и т. д.). (И часть алгоритма планирования потоков затем выполняет такие действия, как предоставление ожидающему потоку некоторого временного «ускорения», когда эти ожидаемые данные становятся доступными. Опять же, обычно вам не нужно слишком сильно об этом беспокоиться.) Или, другими словами: какими бы точными ни были детали этого механизма, он недоступен обычному Java-программисту.

В (2) я бы посоветовал подумать больше о том, «как мне сделать Thing X, который может заблокировать». Я думаю, что вряд ли когда-либо ответом будет то, что Thing You Want To Do намеренно просто «блокируется», и что бы ни было Thing X, вероятно, существует библиотечный метод / класс, который сделает это за вас. Например (ссылки включают некоторые материалы, которые я написал по этим темам):

  • если вы хотите взять следующее сообщение / задание, когда оно станет доступным из какой-либо очереди / провайдера, посмотрите блокировка очередей
  • если вам нужно управлять доступом к общему ресурсу с помощью «блокировки» объекта, ожидая, пока блокировка станет доступной, если необходимо, рассмотрите простой старый синхронизированный или явная блокировка;
  • если вы хотите дождаться, когда станет доступен один из многих объединенные ресурсы, посмотрите семафоры

Я бы сказал, что необработанный механизм ожидания / уведомления в значительной степени устарел с API параллелизма Java 5. И что бы вы ни делали, спин-блокировка обычно является самым последним средством.

Другие вопросы по теме