Параллельное программирование — разговор о прерывании потока

Java задняя часть Безопасность

предисловие

Как прервать поток, точно не используя stop. Вместо этого используйте метод прерывания. В то же время мы знаем, что прерывание потока — это просто флаг. На самом деле не прервет поток, но что, если поток заблокирован?

В Java есть много способов заблокировать поток.

  1. synchronized
  2. Object.wait()
  3. Lock
  4. Condition.await()
  5. LockSupport.park()
  6. Thread.join()

Конечно, выше все очень просто, API не такой подробный. API, такие как Lock, прерываются. И Thread.sleep(). Все это знают, и это должно быть в ответ на прерывания.

Давайте решим нашу задачу ниже.

развеять туман

После тщательного анализа на самом деле есть 2 состояния прерываний: прерывание при работе и прерывание при блокировке.

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

Есть два типа прерываний при блокировке. Один — прерывание при ожидании блокировки, другой — вход в блокировку и прерывание при ожидании.

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

Хотя оба являются состояниями блокировки, эти два состояния блокировки различны.

Основываясь на методах блокировки, описанных в предисловии, давайте проанализируем их один за другим.

В заключение

Интерфейсы Non-Lock, а именно synchronized и Object и связанные с ними методы Thread, кроме synchronized, не будут реагировать на прерывания, другие будут реагировать на прерывания и генерировать исключения.

Интерфейс блокировки, независимо от того, используете ли вы методы блокировки серии или методы серии ожидания Condition, вы можете делать все, что хотите, и вы можете использовать любой режим, который вы хотите. В повседневной разработке эта функция по-прежнему очень полезна.

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

Например, метод сна и метод ожидания очищают состояние прерывания.

После того, как метод серии Lock выдаст исключение, он также очистит статус прерывания.

Средством Lock для очистки прерванного состояния является метод Thread.interrupted.

Зачем очищать статус прерывания? Если поток снова прервется в следующий раз, он может быть оценен в это время.

Немного внимания, разница между статическим методом Thread.interrupted и методом-членом Thraed#isInterrupted()

Все они называются классом Thread.private native boolean isInterrupted(boolean ClearInterrupted)метод.

Этот метод имеет логический параметр, true — очищать состояние прерывания, false — не очищать. Будьте осторожны при его использовании.

Дополнения

Методы ShutDown и ShutDownNow пула потоков останавливают поток, устанавливая прерывание потока.

ShutDown должен дождаться завершения задачи перед выполнением метода прерывания потока пула потоков. ShutDownNow не будет напрямую выполнять метод прерывания.

Таким образом, когда вы выполняете метод ShutDown, вы должны дождаться завершения задачи, прежде чем устанавливать статус прерывания. Методы реагирования на прерывания, заложенные в вашем коде, работать не будут. Что действительно работает, так это переменная состояния, установленная внутри пула потоков. Целью установки прерывания является прерывание потока, заблокированного в очереди.

Когда вы выполняете метод ShutDownNow, пул потоков будет выполнять метод прерывания всех активных потоков, если ваша задача имеет указанные выше методы, которые реагируют на прерывания. Затем поток может быть немедленно прерван. Если нет, честно дождитесь окончания выполнения задачи.

Интересные вещи

Когда рабочий процесс пула потоков инициализирован, для переменной состояния AQS будет установлено значение -1, чтобы пользователь не мог выполнить метод shutdown, чтобы попытаться остановить поток. Когда реальная задача будет выполнена, переменная AQS будет установлена ​​на 0. В это время пользователь выполняет метод ShutDwon, чтобы быть эффективным. А как насчет метода shutdownNow? Точно так же также оценивается, что переменная состояния должна быть больше или равна 0 для выполнения метода прерывания. Убедитесь, что общее состояние пула потоков безопасно.

На самом деле, эта статья все еще немного беспорядочна и слишком много. Но в целом речь все же о прерывании потока.

Знакомство с использованием этих API по-прежнему очень важно для параллельного программирования.

Подвести итог еще раз

Что говорит эта статья:

  1. Какие API, связанные с синхронизацией и блокировками в Java, могут реагировать на прерывания и какие не могут реагировать на прерывания. Подводя итог, можно сказать, что Lock более гибко относится к прерываниям.
  2. Два метода класса Thread для оценки прерывания: статический метод очистит состояние прерывания, а метод-член — нет.
  3. Метод ShutDownNow пула потоков будет решать, следует ли прерывать задачу немедленно, в зависимости от того, есть ли в задаче API, который отвечает на прерывание.Если да, то он будет прерван немедленно, в противном случае он будет ждать завершения задачи. .
  4. Интересный феномен пула потоков: при инициализации Worker переменной присваивается значение -1, чтобы пользователь не мог вызывать методы ShutDown и ShutDownNow во время инициализации.