Лабораторная работа №3: Реализация паттерна читатели - писатель — КиберПедия 

Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

Лабораторная работа №3: Реализация паттерна читатели - писатель

2022-10-10 90
Лабораторная работа №3: Реализация паттерна читатели - писатель 0.00 из 5.00 0 оценок
Заказать работу

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

Итак! «ОткрытьпроектRW». Рассмотрим код.

У нас есть main, который ставит 5 работ «ExecutorService». Как видите, здесь нет никаких рукопашных потоков. Просто пул потоков. Кстати, мне нравится новый синтаксис, как можно сделать sleep:TimeUnit.Seconds.sleep(3) – 3 секунды. Вот еще что мне нравится – можно ждать в дняхTimeUnit.Days.sleep(3). Представьте, что вам нужно подождать 2 часа, и вы в миллисекундах напишете, что это 2 часа. Ну кто же поймет, что это 2 часа? А здесь нормально будет написано.

Короче, поставили 5 работ. Что делает каждая работа? Каждая работа «run»: она читает и говорит «я прочитала», меняет и потом снова повторное чтение идет. Короче, 5 чтений, 5 записей, 5 повторных чтений.

Ну метод, который читает и метод который пишет с буфером и с маленьким sleep, чтобы создать всем проблему, и никаких synchronizeпока что нет. Если я запущу эту программу, то она работает со «страшной» скоростью. Они прямо толпой бросаются, потому что нет синхронизации. Они вперемешку читают-пишут-пишут-читают-пишут, как попало.

Итого:

Дело в том, что у нас в пуле 5 потоков. Онивсе 5 стартуютодновременно, и соответственно, идет 5 чтений, 5 записей, и 5 повторных чтений. Нопосмотритечемусчетчиквконцеравен. 5-увеличений счетчика. Было 0, а стало 1 после 5-кратного увеличения. Бардак.

run: First read pool-1-thread-3 0 First read pool-1-thread-2 0 First read pool-1-thread-4 0 First read pool-1-thread-5 0 First read pool-1-thread-1 0 Write... pool-1-thread-3 0 Write... pool-1-thread-4 0 Write... pool-1-thread-5 0 Write... pool-1-thread-2 0 Write... pool-1-thread-1 0 Second read pool-1-thread-5 1 Second read pool-1-thread-3 1 Second read pool-1-thread-2 1 Second read pool-1-thread-4 1 Secondreadpool-1-thread-1 1 СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 3 секунды)

Итак. Попытка вылечить этот бардак стандартными средствами, которые делать не нужно, потому что это ни к чему хорошему не приведет – это добавление слов synchronizedперед методами readи write. Вы скажете, «ну теперь должно быть все шикарно!». Самое удивительное, это полная и тотальная синхронизация и она все-равно здесь некорректна.

Счетчик-то будет равен 5, сейчас вы увидите. Запускаю F6.

run: First read pool-1-thread-1 0 First read pool-1-thread-5 0 First read pool-1-thread-3 0 First read pool-1-thread-2 0 First read pool-1-thread-4 0 Write... pool-1-thread-2 0 Write... pool-1-thread-3 0 Write... pool-1-thread-5 0 Write... pool-1-thread-1 0 Second read pool-1-thread-5 4 Second read pool-1-thread-3 4 Second read pool-1-thread-2 4 Write... pool-1-thread-4 0 Second read pool-1-thread-1 5 Secondreadpool-1-thread-4 5 СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 6 секунды)

Они читают по очереди. Вот этот synchronized – это сразу потеря производительности. Они читают по отдельности. Конечно же счетчик в конце будет равен 5 раз у нас тотальная синхронизация. Но обратите внимание, что те, кто повторно читал (вот эти и вот эти ребята, которые повторно читали), они получили какое значение? не 5. Т.е. получилось, что за счет того, что «синхронизация», т.е. каждый поток успеет дорваться до объекта и выполнить чтение-запись-чтение самостоятельно по сути проскочив перед другими, то он прочитает «0», а вот потом прочитает при втором чтении «1», потому что только он увеличил на «1». И получается, что изменения, которые были сделаны потом, он их не видит. Т.е. у нас не все повторно прочитали одни и те же данные. Вот в чем проблема. Вот оно какое чтение. У кого 3, у кого 4, у кого 5. И все очень медленно, потому что друг за другом идет даже чтение. Вот видите, этот опоздал с записью и у троих результат второго чтения «4». Т.е. если это фатально для системы, и если нужны всем более обновленные данные, то synchronized тут не к месту. Поэтому как написано в лабораторной работе, мы его стираем, и делаем все как написано по заданию.

Лабораторная совсем не сложная, но сделав ее и запустив программу, вы увидите то, что должно быть: толпа читает, потом по очереди идет запись, и потом снова толпа читает. И при повторном чтении у всех должны быть одинаковые данные. Потому что все, которые хотели менять они накопились и ждали, и когда их пустили, то они все отработали и их всех пропустили, потом снова дали читать. И вот это тоже бизнес-логика и это может оказаться крайне полезным.

Задание:
Упражнение 3 (Реализация паттерна читатели - писатель). - Откройте проект RWв каталоге Лабы Java2/Threads /RW. - Запустите его и обратите вниманиена скорость выполнения и на корректность данных. - Поставьте перед методами «read» и «write»модификатор «synchronized». Как изменилась скорость работы? Что с данными? - Уберите «synchronized». - В класс «Data» добавьте следующие члены класса                           private ReadWriteLock lock = new ReentrantReadWriteLock();                           private Lock rl = lock.readLock();                           private Lock wl = lock.writeLock(); - Используйте объект «rlock» для получения блокировки на чтение в методе «read». Добавьте блок «finally», в котором и снимите блокировку на чтение. - Используйте объект «wlock» для получения блокировки на запись в методе «write». Добавьте блок «finally», в котором и снимите блокировку на запись. - Запустите программу. Оцените скорость работы и корректность данных.

run: First read pool-1-thread-2 0 First read pool-1-thread-4 0 First read pool-1-thread-3 0 First read pool-1-thread-1 0 First read pool-1-thread-5 0 Write... pool-1-thread-1 0 Write... pool-1-thread-2 0 Write... pool-1-thread-4 0 Write... pool-1-thread-3 0 Write... pool-1-thread-5 0 Second read pool-1-thread-2 5 Second read pool-1-thread-1 5 Second read pool-1-thread-4 5 Second read pool-1-thread-5 5 Secondreadpool-1-thread-3 5 СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 3 секунды)

Самое важное отличие от того когда у нас было просто synchronized – это то, что все пятеро все вместе читают. Производительность совсем другая. Пишут по одному. И потом опять все вместе читают. Она работает совсем с другой скоростью. Если в вашей системе происходит 90% чтений, то вы не потеряете здесь производительность.


Поделиться с друзьями:

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

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



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.007 с.