Читаем Многопоточное программирование в Java полностью

В этом примере производителя-потребителя мы создаем два условия для одной блокировки.



И у нас есть два метода для записи и чтения данных.

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

Как только другой поток считал данные мы просыпаемся и записываем данные.

После этого будим другие потоки для считывания данных.

Интерфейс ReadWriteLock — это усовершенствованный механизм блокировки потоков, который позволяет нескольким потокам одновременно читать определенный ресурс, но только одному потоку записывать одновременно.



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

Так как ошибки параллелизма возникают в первую очередь при одновременном считывании и записи в общий ресурс или при одновременном выполнении нескольких записей в общий ресурс.

А здесь запись ограничивается одним потоком.

Правила, по которым потоку разрешено блокировать ReadWriteLock для чтения или записи защищенного ресурса, заключаются в следующем:

Можно блокировать для чтения, если никакие потоки не заблокировали ReadWriteLock для записи, и ни один поток не запросил блокировку записи, но еще не получил ее.

Таким образом, несколько потоков могут удерживать блокировку для чтения.

Можно блокировать для записи, если ни один поток не читает или не записывает.

Таким образом, только один поток может удерживать блокировку для записи.

ReadWriteLock — это интерфейс.

Таким образом, для использования ReadWriteLock пакет java.util.concurrent. locks предоставляет реализацию ReadWriteLock — класс ReentrantReadWriteLock.

Здесь показан простой пример кода, демонстрирующий, как создать ReadWriteLock и как его заблокировать для чтения и записи.

Надо заметить, что ReadWriteLock фактически внутренне хранит два экземпляра Lock. Один защищенный доступ для чтения и один защитный доступ для записи.

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

И для этого Java представляет класс ReentrantReadWriteLock в пакете java.util.concurrent. locks, который обеспечивает такой механизм блокировки.

В политике блокировки он позволяет блокировать чтение одновременно несколькими потоками-читателями, если нет потока-писателя, и блокировка записи является исключительной.

Но позже выяснилось, что у ReentrantReadWriteLock есть серьезные проблемы с голоданием, если они не обрабатываются должным образом.

Использование опции справедливости может помочь, но использование справедливости значительно уменьшает пропускную способность при наличии многих потоков.

Таким образом, поток писателя может попасть в голодание при большом количестве потоков-читателей, а применение для него опции справедливости значительно уменьшит пропускную способность.

В Java 8 добавлен новый тип блокировки StampedLock, который помимо предоставления отдельных блокировок для чтения и записи также имеет функцию оптимистической блокировки для операций чтения.



StampedLock также предоставляет метод обновления блокировки чтения до блокировки записи, которого нет в ReentrantReadWriteLock.

Методы блокировки StampedLock возвращают штамп, представленный значением long.

Вы можете использовать эти штампы, чтобы либо отпустить блокировку, чтобы проверить, является ли блокировка действительной, чтобы преобразовать блокировку.

Если штамп всегда равен нулю, это означает, что не удалось получить доступ к ресурсу.

Имейте в виду, что в StampedLock каждый вызов для получения блокировки всегда возвращает новый штамп и производится блокировка, даже если тот же поток уже содержит блокировку, что может привести к deadlock.

И еще одно замечание — ReadWriteLock имеет два режима управления доступом для чтения и записи, в то время как StampedLock имеет три режима доступа.



При чтении, метод readLock получает неэксклюзивную блокировку. Этот метод возвращает штамп, который можно использовать для разблокировки или преобразования режима.

При записи, метод writeLock получает исключительную блокировку. Этот метод возвращает штамп, который можно использовать для разблокировки или преобразования режима.

Этот метод не будет блокировать и возвращает штамп как ноль, если блокировка не будет немедленно доступна.

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

При оптимистическом чтении, метод tryOptimisticRead возвращает ненулевой штамп только в том случае, если в настоящее время блокировка не удерживается в режиме записи.

При этом используется метод validate для проверки правильности значений, считанных при оптимистичном чтении.

Метод validate возвращает true, если блокировка не была запрошена для записи с момента получения данного штампа.



Может возникнуть ситуация, когда вы приобрели блокировку записи и что-то записали, и вы хотели бы прочитать в том же критическом разделе.

Таким образом, чтобы не нарушать потенциальный параллельный доступ, мы можем использовать метод tryConvertToReadLock для конвертации блокировки и получения доступа для чтения.

Перейти на страницу:

Похожие книги

«Ага!» и его секреты
«Ага!» и его секреты

Вы бы не хотели, скажем, изобрести что-то или открыть новый физический закон, а то и сочинить поэму или написать концерт для фортепьяно с оркестром?Не плохо бы, верно? Только как это сделать? Говорят, Шиллер уверял, будто сочинять стихи ему помогает запах гнилых яблок. И потому, принимаясь за работу, всегда клал их в ящик письменного стола. А физик Гельмгольц поступал иначе. Разложив все мысленно по полочкам, он дожидался вечера и медленно поднимался на гору лесной дорогой. Во время такой прогулки приходило нужное решение.Словом, сколько умов, столько способов заставить мозг работать творчески. А нет ли каких-то строго научных правил? Одинаковы ли они для математиков, биологов, инженеров, поэтов, художников? Да и существуют ли такие приемы, или каждый должен полагаться на свои природные способности и капризы вдохновения?Это тем более важно знать, что теперь появились «электронные ньютоны» — машины, специальность которых делать открытия. Но их еще нужно учить.Решающее слово здесь принадлежит биологам: именно они должны давать рецепты инженерам. А биологи и сами знают о том, как мы думаем, далеко не все. Им предстоит еще активнее исследовать лабораторию нашего мышления.О том, как ведутся эти исследования, как постепенно «умнеют» машины, как они учатся и как их учат, — словом, о новой науке эвристике рассказывает эта книга.

Елена Викторовна Сапарина

Зарубежная компьютерная, околокомпьютерная литература
Создание трилогии BioShock. От Восторга до Колумбии
Создание трилогии BioShock. От Восторга до Колумбии

Всего за три игры сага BioShock заняла особое место в сердцах игроков. Она может похвастаться проработанными и совершенно уникальными персонажами и мирами. Действие первых двух частей происходит в подводном городе Восторг, где игрок погружается в стиль ар-деко и атмосферу 1950-х годов. Третья часть, BioShock Infinite, переносит вас в 1912 год и приглашает исследовать небесный город Колумбия в сеттинге стимпанка.В книге вас ждут:[ul]рассуждение об источниках вдохновения создателя серии Кена Левина;исследование уникального геймплея и механик;подробности разработки игр франшизы от идеи до выпуска;глубокий анализ сюжета, тем и персонажей каждой части.[/ul]Авторы отдают дань уважения популярной серии игр, которая, несмотря на короткую историю, уже получила признание критиков.В формате PDF A4 сохранен издательский макет книги.

Мехди Эль Канафи , Николя Курсье , Рафаэль Люка

Зарубежная компьютерная, околокомпьютерная литература