Вебинары Разобраться в IT Реферальная программа
Программирование Аналитика Дизайн Маркетинг Управление проектами
22 Апр 2023
2 мин
807

Почему использовать ReentrantLock, когда есть synchronized?

Синхронизация важна в многопоточном программировании, поскольку она предотвращает конфликты между потоками, которые могут привести к непредсказуемым

Синхронизация важна в многопоточном программировании, поскольку она предотвращает конфликты между потоками, которые могут привести к непредсказуемым результатам. Java предлагает два основных способа синхронизации: ключевое слово synchronized и класс ReentrantLock.

Пример использования ключевого слова synchronized:

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

В этом примере increment() и getCount() синхронизированы, что означает, что только один поток может выполнять один из этих методов в одно и то же время.

Теперь взглянем на пример с использованием ReentrantLock:

import java.util.concurrent.locks.ReentrantLock;

public class Counter {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

Здесь ReentrantLock используется для того же самого — защиты доступа к переменной count. Но почему бы не использовать synchronized вместо ReentrantLock, ведь он кажется проще?

Есть несколько причин, по которым ReentrantLock может быть предпочтительнее:

  • Больше гибкости: ReentrantLock позволяет попытаться захватить блокировку и отказаться от попытки, если блокировка не доступна. Это не возможно с synchronized.
  • Условное ожидание: ReentrantLock может использоваться с Condition для управления потоками, которые пока не могут продолжить работу.
  • Возможность прерывания блокировки: Если поток ожидает блокировки, то его можно прервать, вызвав lockInterruptibly().

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

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей

Добавить комментарий