Thread Safety of Beans in Spring Framework

Thread safety in Spring beans depends on their scope. Spring supports multiple bean scopes, with Singleton and Prototype being the most commonly used.

By default, Spring beans are singletons, meaning a single instance exists per Spring IoC container. In contrast, prototype-scoped beans create a new instance each time they are requested from the container.

Prototype beans are inherently thread-safe because each thread operates on a separate instance, eliminating shared state concerns.

Singleton beans may face thread safety issues, but this is not guaranteed—it hinges on whether the bean contains shared mutable state. For example:

@Service
public class CounterService {
    private int counter = 0;

    public int increase() {
        return ++counter;
    }
}

In this singleton bean, the counter field is shared across threads. Concurrent invocations of increase() can lead to inocrrect values, making it non-thread-safe. Such beans are stateful, requiring explicit thread safety measures.

Stateless singleton beans, which lack mutable instance variables or have read-only fields, are thread-safe. For instance:

@Service
public class CalculatorService {
    public int incrementValue(int value) {
        return value + 1;
    }
}

In summary:

  • Prototype bean are thread-safe.
  • Stateless singleton beans are thread-safe.
  • Stateful singleton beans are not thread-safe.

Ensuring Thread Safety for Stateful Beans

  1. Change Scope to Prototype Setting the bean scope to prototype avoids thread safety issues by providing isolated instances.

    @Scope("prototype")
    @Service
    public class CounterService {
        private int counter = 0;
        // Additional methods
    }
    

    Note that prototype beans incur performance overhead due to frequent instance creation and increased memory usage.

  2. Apply Synchronization Using locks, such as the synchronized keyword, can enforce thread safety but may reduce concurrency and system throughput.

    @Service
    public class CounterService {
        private int counter = 0;
    
        public synchronized int increase() {
            return ++counter;
        }
    }
    
  3. Utilize Concurrent Utilities Java’s concurrency utilities, like atomic classes, offer thread-safe operations with better performance.

    import java.util.concurrent.atomic.AtomicInteger;
    
    @Service
    public class CounterService {
        private AtomicInteger counter = new AtomicInteger(0);
    
        public int increase() {
            return counter.incrementAndGet();
        }
    }
    

    This approach is recommended for balancing thread safety and efficiency.

Tags: Spring Framework Bean Scope Thread Safety singleton Prototype

Posted on Fri, 11 Sep 2026 16:01:38 +0000 by SuperTini