Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
java all-in-one.docx
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
1.97 Mб
Скачать

26. Потоки выполнения. Синхронизация и сигнализирование с помощью Lock.

Web-приложений (Thin Client) выдвигаются требования одновременной поддержки многих пользователей, каждому из которых выделяется отдельный поток, а также разделения и параллельной обработки информационных ресурсов. Потоки – средство, которое помогает организовать одновременное выполнение нескольких задач, каждую в независимом потоке. Потоки представляют собой классы, каждый из которых запускается и функционирует самостоятельно, автономно (или относительно автономно) от главного потока выполнения программы. Существуют два способа создания и запуска потока: расширение класса Thread или реализация интерфейса Runnable.

Наверняка если вас спросить о средствах синхронизации потоков в Java 1.4, каждый сразу же вспомнит synchronized блоки или целые методы. Безусловно, они достаточно просты в использовании, но тем не менее обладают рядом недостатков, которые мы рассмотрим чуть ниже. synchronized (object) { //действия внутри синхронизованного блока } Среди основных недостатков synchronized блоков можно выделить следующие:

  • Не существует способа отказаться от попытки захватить какой-либо объект, если он занят, отсутствует возможность отказаться от попытки захвата объекта через какой-то интервал времени. Имея все эти возможности, проблема появления deadlock при синхронизации потоков была бы не так актуальна.

  • Не существует способа осуществлять отдельные блокировки для чтения или записи, что местами бывает весьма полезно. При освобождении некоторого захваченного ресурса (того, который выступает параметром у вызова synchronized блока) нет возможности специально дать доступ к этому блоку самому первому потоку, который раньше других начал пытаться его захватить.

  • Если существует несколько вложенных synchronized блоков, то освобождены ресурсы должны быть строго в обратном порядке по сравнению с тем, в котором они были захвачены. Базовые Lock объекты

В Java 1.5 были введены так называемые внешние блокировки. Т.е. программист сам может выбирать моменты начала и окончания каждой блокировки. Базовым интерфейсом для таких блокировок является java.util.concurrent.locks.Lock. Lock l = …; l.lock(); try { // доступ к защищенным ресурсам } finally { l.unlock(); } Среди основных методов, использующихся для начала защищенного блока, можно выделить следующие:

  • void lock() – начало защищенного блока. В случае занятости ресурса происходит ожидание его освобождения.

  • boolean tryLock() – попытка получить блокировку, если она свободна на момент вызова метода. Если нет, то возвращается значение false и программа продолжает свое выполнение.

  • boolean tryLock(long time, TimeUnit unit) – попытка получить блокировку в течение некоторого интервала времени. Если она не удачна, то возвращается значение false и программа продолжает свое выполнение.

Базовой реализацией интерфейса Lock является класс ReentrantLock. Конструктор данного класса может принимать так называемое значение честности, т.е. индикатор того, должен ли первый совершивший попытку поток получить доступ к освобожденному ресурсу. Следует отметить, что использование этой возможности может негативно сказаться на производительности приложения. Рекомендуется создавать «честный» ReentrantLock только в том случае, если это действительно необходимо. Lock объекты для чтения и записи В Java 1.5 стало возможным отдельно управляться блокировкой для чтения и записи данных, что безусловно является весьма удобным. Блокировка для чтения может одновременно быть захвачена несколькими потока, в то время как блокировка на запись является эксклюзивной только для одного конкретного потока. Такое разделение положительным образом влияет на производительность приложения, т.к. чтением информации могут заниматься несколько потоков одновременно. В частности данный вид блокировок можно применить для работы с коллекциями, к которым основной процент обращений связан с чтением информации, и только изредка присутствуют её обновления. Базовой реализацией интерфейса ReadWriteLock является ReentrantReadWriteLock. Выделим основные его особенности:

  • Как и ReentrantLock поддерживает «честный» и «нечестный» режим работы.

  • Не отдает какого-либо предпочтения потокам для чтения или записи при получении блокировки.

  • Поддерживается прерывание процесса получения блокировки.

  • Если для текущего потока блокировка захвачена читателем, то писатель не может её получить. Обратное же верно.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]