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

Почему использовать 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 предоставляет больше возможностей.

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