Синхронизация важна в многопоточном программировании, поскольку она предотвращает конфликты между потоками, которые могут привести к непредсказуемым результатам. 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 предоставляет больше возможностей.
Перейти в телеграм, чтобы получить результаты теста



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