Насколько я понимаю, когда кто-то вызывает interrupt
в потоке, он просто устанавливает флаг статуса потока. прерванный поток несет ответственность за периодическую обработку прерывания.
проверив, прервано оно или нет
или
вызвать метод, который выдает interruptedException
, который, в свою очередь, проверяет наличие флага, вызывающего исключение
Теперь, как это делает поток, который находится в режиме сна?
Метод interrupt()
только проверяет состояние потока, видит, что он спит, и вызывает исключение.
если это так, то же самое происходит и с методом wait()
?
Краткий ответ:
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
уведомляют ОС о том, что собственный поток должен снова запуститься (а затем проверяется причина, по которой он был повторно активирован).
повторно «уведомить ОС» — я почти уверен, что в большинстве систем это поддерживается вплоть до аппаратного уровня. По сути, это примитив, и «как работает прерывание» в этом отношении чем-то похоже, скажем, на «как работает добавление двух целых чисел». (И просто для ясности: я не говорю, что ваш ответ неправильный или неполный, просто даю к нему небольшой дополнительный комментарий. :))
Пожалуйста, отредактируйте свой вопрос, включив в него используемую вами реализацию/версию JDK, поскольку она, скорее всего, зависит от JDK. Реализация OpenJDK может отличаться от реализации других JDK.