Ответ
Нет, по умолчанию Singleton-бин в Spring не является автоматически потокобезопасным. Его потокобезопасность зависит от наличия и управления изменяемым состоянием (mutable state).
- Stateless-бины (без состояния) безопасны: Если бин только содержит логику или финальные/неизменяемые данные, он безопасен для использования из множества потоков.
- Stateful-бины (с состоянием) требуют защиты: Если бин имеет изменяемые поля, разработчик должен самостоятельно обеспечить синхронизацию доступа.
Пример потоконебезопасного Singleton-бина:
@Service // По умолчанию Scope = Singleton
public class UnsafeCounterService {
private int count = 0; // Изменяемое состояние, общее для всех потоков
public void increment() {
count++; // Неатомарная операция (чтение-изменение-запись)
}
}
Способы обеспечения потокобезопасности:
-
Использование атомарных классов из
java.util.concurrent.atomic:@Service public class SafeCounterService { private final AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); // Атомарная и потокобезопасная операция } } - Синхронизация (менее предпочтительно из-за производительности):
public synchronized void increment() { count++; } - Использование потокобезопасных коллекций (например,
ConcurrentHashMap).
Вывод: Spring управляет жизненным циклом одного экземпляра Singleton-бина, но не гарантирует его потокобезопасность. Ответственность лежит на разработчике.