Ответ
Нет, по умолчанию singleton-бин в Spring не является потокобезопасным.
Почему? Spring управляет жизненным циклом singleton-бина, создавая один экземпляр на IoC-контейнер, который затем используется всеми запросами и потоками. Если состояние этого бина изменяемое (mutable), возникает состояние гонки (race condition).
Пример проблемного кода:
@Component // По умолчанию scope = "singleton"
public class UnsafeCounterService {
private int count = 0; // Изменяемое состояние
public void increment() {
count++; // Неатомарная операция, небезопасна для потоков
}
public int getCount() {
return count;
}
}
Как обеспечить потокобезопасность?
- Старайтесь создавать stateless-бины: Без изменяемых полей. Это лучшая практика.
- Используйте synchronized или атомарные классы из
java.util.concurrent.atomic:private final AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); } - Храните состояние в ThreadLocal переменных, если оно должно быть уникальным для потока.
- Измените область видимости бина на
prototype,requestилиsession, если логика требует отдельных экземпляров. Однако это влияет на производительность и память.
Вывод: Потокобезопасность singleton-бина — это ответственность разработчика, а не контейнера Spring.