Java EE component life cycle and concurrency related details might not be new for seasoned professionals, but it is something which can take time to sink in for beginners.

As far as EJBs are concerned, understanding their life cycle (and related concurrency scenarios) is extremely critical in order to ensure appropriate usage and solution design using EJBs. It’s easy to misuse them!

Bean Life Cycle

I’ll quickly cover Stateless and Stateful beans in this post and skip Lima Beans for the time being.

Stateful Session Beans – life cycle + concurrency handling

Stateless beans – concurrency model only, since I had briefly covered the lifecycle in one of my previous posts.

What are the distinct states in the life cycle of a Stateful Session Bean?

Does Not Exist

Ready

Passivated

How do the states change? What triggers them?

Here is a quick tabular snap shot and a high level diagram. For more details, read on . . .

The EJB container passivates idle beans and removes them from active memory based on specific algorithms

@PrePassivate

P to DNE

The bean reaches idle time out threshold designated by DD or @StatefulTimeout

Note: @PreDestroy annotated method is NOT invoked

P to R

When the client invokes a SFSB instance after it is passivated but has not timed out yet

@PostActivate

Note: If a SFSB throws an exception during request processing, its instance is destroyed i.e. it goes to a DNE state. The @PreDestroy annotated method is not invoked in this case

Now that we have some idea about the life cycle of a SFSB, let’s try to take a look at how do these beans behave under load i.e. when the application is used by multiple users at a time which translates into concurrent access of SFSB instances

Stateful Session Beans: Concurrency Management

Thread safety is one of the core features of EJBs. The point to be noted is that this thread safety is free of cost and does not need any concurrency related constructs to be coded in by the bean developer himself (there are a few exceptions). As far as SFSB are concerned, the EJB container ensures that only one thread can access a bean instance at a particular time.

In this example, we are trying to simulate concurrent access to a single instance of a SFSB by invoking a test Servlet via JMeter. The Servlet injects the bean via DI and calls a method on it. The SFSB method just uses a Thread.sleep() to pretend as if it’s executing something.

Since a Servlet itself is not thread safe, multiple threads will in fact enter the doGet() method

A single instance of the SFSB (evident via the hashCode result) in being accessed concurrently (see the thread names in the logged statements)

Only one thread will be able to access the SFSB instance though – other threads wait for their turn while the SFSB method returns. This delay is noticeable via the log statements on the console

Console logs

What about Stateless Beans?

These beans are
inherently thread safe.
Why? It is because by default, the container makes sure that
each new request is served by a new instance of the bean. Remember, that a client can obtain a reference to stateless bean in 3 possible ways – DI, JNDI or via a remote interface (RMI). In all these cases, it is the container (proxy) which intercepts the call – thus, even if multiple threads are seemingly accessing the same bean instance, its actually not the same on.