Назад к вопросам
Middle+
89
questionbank

Как сделать метод потокобезопасным, чтобы он не мог быть вызван из другого потока, пока выполняется в одном потоке?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Используйте ключевое слово synchronized для метода.

class SafeCounter {
    private int count = 0;

    public synchronized void increment() {
        // Этот блок кода будет выполняться только одним потоком одновременно
        count++;
    }

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

Также можно использовать synchronized блок с монитором объекта.

class AlternativeSafeCounter {
    private int count = 0;
    private final Object counterLock = new Object(); // Создаем объект-монитор

    public void increment() {
        synchronized (counterLock) { // Синхронизация по объекту counterLock
            count++;
        }
    }

    public int getCount() {
        synchronized (counterLock) { // Синхронизация по объекту counterLock
            return count;
        }
    }
}

Другие механизмы для более сложной синхронизации:

  • ReentrantLock: Более гибкая альтернатива synchronized с возможностью получения информации о блокировке и управлением таймаутами.
  • Semaphore: Ограничивает количество потоков, которые могут одновременно получить доступ к ресурсу.
  • Atomic классы (например, AtomicInteger): Предоставляют атомарные операции над примитивными типами без явной блокировки.

Пример с AtomicInteger:

import java.util.concurrent.atomic.AtomicInteger;

class AtomicCounter {
    private final AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet(); // Атомарная операция инкремента
    }

    public int getCount() {
        return count.get();
    }
}