Ваше утверждение "любое количество потоков может войти в блок synchronized
" ложно.
Теоретически, если один поток находится внутри блока synchronized
, это препятствует проникновению других потоков.Это невозможно в случае IntentService
, поскольку IntentService
использует один рабочий поток для обработки рабочей нагрузки.
Вызов wait()
- это метод синхронизации потоков, а не метод задержки.Это отличается от вызова sleep()
, который просто блокирует поток на определенное время.Когда вы вызываете wait()
, это блокирует поток, пока другой поток не вызовет notify()
, который используется для координации действий между несколькими потоками.wait(10000)
блокирует поток до тех пор, пока либо notify()
не будет вызван из другого потока ИЛИ, пока не истечет время ожидания (в данном случае 10 секунд).Таким образом, похоже, что где-то должен быть другой поток, который вызывает notify()
объекта IntentService
, чтобы разбудить его.
Здесь есть дополнительная сложность, связанная с использованием notify()
и wait()
.Чтобы вызвать любой из этих методов, сначала необходимо получить блокировку на мониторе объекта (с помощью synchronized
).Это означает, что вызовы wait()
и notify()
должны быть в пределах synchronized
блоков или в synchronized
методах, которые synchronized
для объекта.
Поток, который вызывает wait()
, фактически освобождаетзамок на объекте.Это означает, что поток заблокирован внутри synchronized
блока / метода, но у него нет блокировки объекта во время ожидания .После вызова notify()
(или по истечении времени ожидания) поток восстановит блокировку объекта и продолжит выполнение.
Для получения дополнительной информации об использовании notify()
и wait()
в Java найдитеэти термины и читайте об этом.
Этот код довольно запутанный, если все, что он должен сделать, это задержать 10 секунд, а затем написать что-то для logcat.Вы можете просто позвонить sleep()
вместо wait()
, что не потребует оператора synchronized
.Однако, как отметил другой автор, если этот Service
вызывается очень часто, это создаст отставание, так как каждый вызов onHandleIntent()
будет задерживаться на 10 секунд, и поскольку существует только 1 рабочий поток, все вызовы сериализуются.,Пример: звонок на startService()
сделан в 10:00:00, запись в logcat появится в 10:00:10.Если в 10:00:01 будет сделан другой вызов startService()
, эта запись не будет отображаться в журнале до 10:00:20, поскольку второй вызов onHandleIntent()
не произойдет до 10:00: 10.