Механизм прерывания потока обеспечивает метод для разбуждения потока от блокирующего ожидания, пытаясь прервать существующий поток обработки целевого потока и реагировать на новые команды. Java оставляет эту свободу для разработчиков, и мы должны хорошо использовать ее.
Сегодня мы поговорим о механизме прерывания нитей Java.
Механизм прерывания потока обеспечивает метод, который имеет два общих применения:
Разбудите поток от блокировки ожидания и сделайте соответствующую обработку «контролируемого прерывания».
Попробуйте проинформировать целевой поток: пожалуйста, прервайте существующий поток обработки и ответьте на новые команды.
Возьмите первую цель в качестве примера, см. Следующий код:
Synchronized (lock) {try {while (! check ()) {lock.wait (1000); }} catch (прерывание Exception e) {e.printStackTrace (); }}Этот код использует механизм ожидания/уведомления, предоставленный Java. Выполнение потока блокировки. Wait () будет блокировать. Есть три ситуации, чтобы восстановить поток для запуска.
1. Тайм -аут 1000 мс заканчивается, а следующий код выполняется нормально.
2. Другой поток выполняет следующий код, чтобы активно проснуться
синхронизированный (lock) {lock.notifyall (); // или lock.notify ();}Это также будет выполнять следующий код нормально.
3. Еще один поток, который необходим для ожидания, - это «прерывание»
// Получить ссылку на резьбу для ожидания a; A.Intertrupt ();
Поток A, который «прерывается», выбросит исключение прерванного эктриэкцены на lock.wait ().
Подводя итог, вы можете подумать, что Object.Wait () делает это внутри:
boolean checktimeout = timeout> 0; think current = think.currentThread (); lock.addwaiter (current); while (! current.isnotified ()) {if (current.IsErrupted ()) {current.clearErrupting (); выбросить новый прерываний (); } if (cecktimeout) {if (timeout == 0) break; Тайм-аут ...; }}Это не совсем точно, потому что ожидание не использует этот метод «занятого опроса» для проверки, но логика судейских флаг -битов верна.
Давайте начнем с операции «Вручную прерывания», упомянутой выше
// sun.nio.ch. intertiblepublic interface Interrutible {void прерывание (поток var1);} // java.lang.threadprivate volatile прерываемого блокировщика; частный окончательный объект блокировки = new object (); public void Interrupt () {if (this! синхронизированный (Blockerlock) {прерывим B = блокировщик; if (b! = null) {enterrupt0 (); B.interrupt (это); возвращаться; }} enterrupt0 ();} // Просто чтобы установить прерывание флагривата нативного void enterrupt0 ();Можно видеть, что Thread.interrupt () сначала судей разрешений, а затем фактически вызывает enterrupt0 (), чтобы установить флаг прерывания потока. Если текущий поток имеет прерывание NIO, он также перезвонит.
Обратите внимание, что Enterrupt0 () просто устанавливает флаг прерывания потока.
Что происходит, когда поток не блокируется и не находится в областях, которые не управляются логикой программы Java, такими как object.wait (), thread.join (), thread.sleep ()? Ответ заключается в том, что ничего не произойдет, и может ли прерван поток, может быть известно только по активной проверке флага прерываний.
Как проверить? Поток обнаруживает два интерфейса, Thread.Erenprupted () и Think.isErenterted ().
// java.lang.threadpublic static boolean urrepted () {return currentThread (). isErendrupted (true);} public boolean isErengroupted () {return isErenptated (false);} Частный нативный логический IsErenpted (Boolean ClearErrupted);Можно видеть, что оба полагаются на внутреннюю беспрертированную (логическую), которая вернет, прерывается ли поток, и очистит флаг прерывания по мере необходимости.
Когда функция вызовов блокирует, функция библиотеки Java отмечает отбросы перерывы в блокирующей подписи источника и требует, чтобы для обработки прерываний для обработки прерываний.
Когда поток блокирует, как упомянуто выше, Java проверяет флаг прерывания, сначала очищает его, а затем бросает прерывание.
// java.lang.objectpublic final void wat () бросает прерывания, {wait (0);} public final final void wat (длительный тайм -аут) броски прерываетЕсли поток получает прерывание, а затем выполняет код, который бросит блокировку, он будет продолжать блокировать как «независимо от». Потому что Java очищает флаг прерывания внутренне!
Мы часто пишем следующие три типа кода, которые обрабатывают прерывание
Обработайте прерывавшее эклектику к верхнему слою для обработки.
public void foo () бросает прерванную экзенцию {synchronized (lock) {lock.wait (); }}Прерывание эктриэкцепции сбросить бит флага прерываний.
try {synchronized (lock) {lock.wait (); }} catch (прерывание Exception e) {thread.currentThread (). Enterrupt (); //перерыв; }Сначала завершите свою работу, а затем снова бросьте прерывание.
public void bar () бросает прерванную экзантику {прерывание, т.е. = null; логический закончен = false; while (! ed) {synchronized (lock) {try {lock.wait (); } catch (прерванная экспрессия e) {ie = e; продолжать; }} end = true; } if (ie! = null) {throw IE; }}Если поток игнорирует флаг прерывания и прерывание, он все еще работает хорошо. Но это противоречит нашему первоначальному намерению проектирования многопоточного чтения. Мы хотим, чтобы потоки гармонично и упорядоченно сотрудничали для достижения конкретных функций, поэтому контролируемые потоки должны реагировать на прерывания. И мы должны хорошо использовать эту свободу, оставленную Java для разработчиков.
Выше приведено все соответствующие знания о механизме прерывания потока Java, введенного вам на этот раз. Если вы ничего не понимаете, вы можете обсудить это в области сообщений ниже. Спасибо за поддержку Wulin.com.