InterruptedException: откуда Thread#sleep знает

Насколько я понимаю, когда кто-то вызывает interrupt в потоке, он просто устанавливает флаг статуса потока. прерванный поток несет ответственность за периодическую обработку прерывания.

  1. проверив, прервано оно или нет

    или

  2. вызвать метод, который выдает interruptedException, который, в свою очередь, проверяет наличие флага, вызывающего исключение

Теперь, как это делает поток, который находится в режиме сна?

Метод interrupt() только проверяет состояние потока, видит, что он спит, и вызывает исключение.

если это так, то же самое происходит и с методом wait()?

Пожалуйста, отредактируйте свой вопрос, включив в него используемую вами реализацию/версию JDK, поскольку она, скорее всего, зависит от JDK. Реализация OpenJDK может отличаться от реализации других JDK.

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

Ответы 1

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

Установите флажок, отмените парковку и включитесь.

Краткий ответ:

Thread.interrupt() не только устанавливает флаг прерывания, но также вызывает собственный метод Thread.interrupt0(), который пробуждает Thread.sleep() потоки, отменяет парковку потоков в LockSupport.park() и пробуждает потоки в Object.wait().


Обратите внимание, что в приведенных ниже фрагментах опущены подробности. Если вам нужен полный исходный код, либо перейдите по ссылкам на репозиторий OpenJDK Github, либо загрузите полные исходные коды.

Если вы посмотрите на исходный код Thread.interrupt(), вы увидите, что он делает три вещи:

interrupted = true;
interrupt0();  // inform VM of interrupt
// thread may be blocked in an I/O operation
Interruptible b = nioBlocker;
b.interrupt(this);

Метод Thread.interrupt0()сопоставлен с методом JVM JVM_Interrupt:

{"interrupt0",       "()V",        (void *)&JVM_Interrupt},

Этот метод находит экземпляр JavaThread (класс C++), который является собственным аналогом java.lang.Thread, и вызывает метод прерывания для этого экземпляра:

bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
receiver->interrupt();

Затем метод JavaThread.interrupt() пробуждает и отпарковывает поток:

  // For Thread.sleep
  _SleepEvent->unpark();

  // For JSR166 LockSupport.park
  parker()->unpark();

  // For ObjectMonitor and JvmtiRawMonitor
  _ParkEvent->unpark();

Эти различные методы unpark уведомляют ОС о том, что собственный поток должен снова запуститься (а затем проверяется причина, по которой он был повторно активирован).

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

yshavit 27.08.2024 19:50

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