Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Справочник Java

ReentrantLock

Явная блокировка — гибкая замена `synchronized`.

Доступно с: Java 1.5

Синтаксис

public class ReentrantLock implements Lock

Примеры

Обязательный unlock() в finally:

class Account {
    private final ReentrantLock lock = new ReentrantLock();
    private int balance = 100;
 
    boolean withdraw(int amount) {
        lock.lock();
        try {
            if (balance < amount) return false;
            balance -= amount;
            return true;
        } finally {
            lock.unlock();
        }
    }
 
    int balance() { return balance; }
}
 
void main() throws InterruptedException {
    var acc = new Account();
    var ok = new AtomicInteger();
    Runnable task = () -> { for (int i = 0; i < 10; i++) if (acc.withdraw(10)) ok.incrementAndGet(); };
    Thread a = new Thread(task), b = new Thread(task);
    a.start(); b.start();
    a.join(); b.join();
    IO.println(ok.get() + " withdrawals, balance " + acc.balance());
}

Результат:

10 withdrawals, balance 0

Примечания

Всегда вызывайте unlock() в finally, иначе после исключения блокировка останется навсегда. В отличие от synchronized, умеет ждать с таймаутом (tryLock(1, TimeUnit.SECONDS)), прерываться и работать в «честном» режиме. Если эти возможности не нужны, synchronized проще.

См. также

  • synchronized — Разрешает выполнять блок кода только одному потоку за раз.
  • AtomicInteger — Целое число, которое можно безопасно менять из нескольких потоков без блокировок.

В учебнике

  • Синхронизация — Гонка данных в Java и как её избежать — synchronized-методы и блоки, атомарные классы AtomicInteger, ReentrantLock и общий объект блокировки.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.