Обратите внимание на братский байт кода общедоступного номера, чтобы разблокировать больше параллелизма.
существуетПоймите принцип синхронизированногоописано вSynchronize
Принцип реализации, будь то синхронизированный метод или синхронизированный блок кода, будь тоACC_SYNCHRONIZED
все ещеmonitorenter
,monitorexit
основаны наMonitor
Реализовано, то в этой статье будет представлено то, чтоMonitor.
Так называемый процесс мониторинга: относится к управлению общими переменными и рабочему процессу общих переменных, чтобы они поддерживали параллелизм. В переводе на Java нужно управлять переменными-членами и методами-членами класса, чтобы класс был потокобезопасным.
Это структура программы, в которой несколько рабочих потоков образованы несколькими подпрограммами (объектами или модулями) в структуре взаимоисключающего доступа к общим ресурсам. Эти общие ресурсы обычно представляют собой аппаратные устройства или группу переменных. Монитор реализует, что не более одного потока выполняет подпрограмму монитора в определенный момент времени. Реализации мониторинга значительно упрощают программирование по сравнению с параллельным программированием, где взаимоисключающий доступ достигается путем изменения структур данных. Монитор предоставляет механизм, с помощью которого поток может временно отказаться от своего доступа к мьютексу, дождаться выполнения определенных условий, а затем восстановить право выполнения для восстановления своего доступа к мьютексу.
модель МЕСА
В истории развития монитора последовательно появлялись три разные модели монитора, а именно:Hasen
Модель,Hoare
модель иMESA
Модель. Среди них широко используетсяMESA
модель иJava
Ссылка на реализацию монитора такжеMESA
Модель. Итак, сегодня мы сосредоточимся на MESA
Модель.
В области параллелизма есть две основные проблемы: одна — взаимное исключение, а другая — синхронизация. Монитор должен решить эти две проблемы.
- Взаимное исключение: только одному потоку разрешен доступ к общему ресурсу в каждый момент времени.
- Синхронизация: как потоки общаются и сотрудничают.
Отслеживание взаимного исключения и синхронизации
Его идея очень проста, он единообразно инкапсулирует общие переменные и операции над общими переменными. Как показано на рисунке ниже, монитор A ставит в очередь данные общих переменных и связанные с ними операции.enq()
, внеdeq()
инкапсулированный. Поток A и поток B хотят получить доступ к данным общих переменных, только вызвав предоставленный монитор.enq()
иdeq()
. Конечно, предпосылка в том, чтоenq()
,deq()
Взаимное исключение гарантируется, и только один поток может войти в монитор. Он очень объектно-ориентирован?
В модели монитора общие переменные и операции над общими переменными инкапсулированы, а крайний прямоугольник на рисунке представляет значение инкапсуляции. Над ложей только один вход, а рядом с входом стоит очередь ожидания входа. Когда несколько потоков пытаются войти в монитор одновременно, вход разрешен только одному потоку, а другие потоки ждут в очереди ожидания входа. Этот процесс похож на сортировку медицинских процедур, только один пациент допускается к врачу, а остальные ждут у двери.
В монитор также введена концепция переменных состояния, иДля каждой условной переменной существует очередь ожидания, как показано на рисунке ниже, условная переменная A и условная переменная B имеют свои собственные очереди ожидания соответственно.
Условные уведомления используются для пробуждения потоков, ожидающих в очереди, чтобы конкурировать за ресурсы блокировки.
Мы используем фрагмент кода, чтобы проиллюстрировать реализацию блокирующей очереди.Очередь имеет dequeue и enqueue соответственно.Все они должны сначала получить мьютекс, как и запись в мониторе.
- Для операции постановки в очередь, если очередь заполнена, вам нужно подождать, пока очередь не заполнится, поэтому здесь мы используем
notFull.await();
. - Для операции удаления из очереди, если очередь пуста, вам нужно подождать, пока очередь не станет пустой, поэтому используйте
notEmpty.await();
. - Если очередь прошла успешно, то очередь не пуста, нужно сообщить переменную условия: очередь не пуста
notEmpty
соответствующую очередь ожидания. - Если удаление из очереди прошло успешно, очередь не заполнена, и необходимо уведомить переменную условия: очередь не заполнена
notFull
соответствующую очередь ожидания.
public class BlockedQueue<T>{
final Lock lock = new ReentrantLock();
// 条件变量:队列不满
final Condition notFull = lock.newCondition();
// 条件变量:队列不空
final Condition notEmpty = lock.newCondition();
// 入队
void enq(T x) {
lock.lock();
try {
while (队列已满){
// 等待队列不满
notFull.await();
}
// 省略入队操作...
// 入队后, 通知可出队
notEmpty.signal();
}finally {
lock.unlock();
}
}
// 出队
void deq(){
lock.lock();
try {
while (队列已空){
// 等待队列不空
notEmpty.await();
}
// 省略出队操作...
// 出队后,通知可入队
notFull.signal();
}finally {
lock.unlock();
}
}
}
В этом примере кода мы используем блокировку и условие в параллельном пакете Java. Неважно, если вы внимательно посмотрите на него. Мы представим его подробно позже. Этот пример просто дает вам понять, как переменная условия и ее очередь ожидания есть. нужно знать, это:await() имеет ту же семантику, что и wait(), о которой мы упоминали ранее; signal() имеет ту же семантику, что и notify(), о которой мы упоминали ранее.. Монитор обеспечивает синхронизацию посредством связи с условной очередью, что обеспечивает базовую поддержку параллельного программирования в нашей Java.
Обратите внимание на братский байт кода общедоступного номера, чтобы получить больше принципов параллелизма.
плечи гигантов
Компьютерное время