LockSupport
Парковка/отмена парковки, предоставляемая LockSupport, разработана с точки зрения потоков, что действительно отделяет синхронизацию между потоками.
основной метод
- Метод park() выполняет операцию блокировки текущего потока и не разблокирует его до тех пор, пока не будет получена доступная лицензия, что эквивалентно переходу текущего потока в заблокированное состояние.
Метод park также может возвращать значение «без причины» в любое другое время, поэтому его обычно нужно вызывать в цикле, который перепроверяет условие возврата. park не освобождает ресурсы блокировки, занятые текущим потоком.
- Метод parkNanos(long) выполняет операцию блокировки в текущем потоке и ожидает разблокировки доступной лицензии.Максимальное время ожидания задается входящим параметром.По истечении максимального времени он также разблокируется.
- Метод parkUntil(long) выполняет операцию блокировки текущего потока и разблокирует его после получения доступной лицензии, максимальное время ожидания — крайний срок, указанный в параметре.
- Метод park(Object) является синонимом метода park(), но параметр, который он передает, является блокирующим объектом.
- Метод parkNanos(Object,long) является синонимом метода parkNanos(long), но определяет блокирующий объект.
- Метод parkUntil(Object, long) является синонимом parkUntil(long), но указывает блокирующий объект.
- Метод unpark(Thread) делает доступным разрешение указанного потока, что эквивалентно пробуждению потока.
Механизм лицензирования
Разрешение, используемое LockSupport, можно рассматривать как двоичный сигнал, и сигнал имеет два состояния: разрешение и отсутствие разрешения. Каждый поток соответствует сигнальной переменной. Когда поток вызывает парк, он фактически получает лицензию. Если лицензия может быть успешно получена, она может быть выполнена, в противном случае она будет заблокирована до тех пор, пока лицензия не будет успешно получена. Когда поток вызывает unpark, он освобождает разрешение на получение потока. Порядок выполнения режима парковки/непарковки не влияет на пробуждение и не приводит к взаимоблокировке.
реакция парка на прерывание
Метод park поддерживает прерывание, то есть после того, как поток вызывает метод park для блокировки, если поток прерывается, он может разблокироваться и немедленно вернуться. Но обратите внимание, что он не генерирует InterruptedException, поэтому нам не нужно перехватывать InterruptedException.
Разница между Thread.sleep() и LockSupport.park()
- Функционально методы Thread.sleep() и LockSupport.park() похожи тем, что они блокируют выполнение текущего потока, и ни один из них не освобождает ресурсы блокировки, занятые текущим потоком;
- Thread.sleep() не может быть разбужен извне и может проснуться только сам по себе, метод LockSupport.park() может быть разбужен другим потоком, вызвавшим метод LockSupport.unpark();
- InterruptedException выбрасывается при объявлении метода Thread.sleep(), поэтому вызывающему объекту необходимо перехватить это исключение или выдать его снова, методу LockSupport.park() не нужно перехватывать прерванное исключение;
Разница между Object.wait() и LockSupport.park()
- Метод Object.wait() должен выполняться в синхронизированном блоке, LockSupport.park() может выполняться где угодно;
- Метод Object.wait() объявляет, что выброшено исключение прерывания, и вызывающая сторона должна перехватить или выдать его снова, LockSupport.park() не нужно перехватывать исключение прерывания;
- Object.wait() без тайм-аута требует, чтобы другой поток выполнил notify() для пробуждения, но не обязательно продолжает выполнять последующее содержимое; LockSupport.park() не имеет тайм-аута, требует, чтобы другой поток выполнил unpark() для пробуждения , Последующий контент будет продолжен;
- Если notify() выполняется до wait(), будет сгенерировано исключение IllegalMonitorStateException;
- Если поток unpark() выполняется перед park(), поток не будет заблокирован, пропустит park() напрямую и продолжит выполнение последующего содержимого;