EJB 3.x : Lifecycle and Concurrency models (part 1)

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.

 
 
 
 
 
 
 
 
concurrency

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

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 . . .

Stateless Session Bean Life Cycle State diagram

Stateless Session Bean Life Cycle State diagram

Note: DNE – Does Not Exist, R – Ready, P – Passivated, SFSB – Statelful Session Bean
 

State TransitionTriggersCallbacks
DNE to RWhen a SFSB instance is first accessed via JNDI or DI@PostConstruct
R to DNEContainer shuts down, client invokes method annotated with @Remove, the bean reaches idle time out threshold designated by DD or @StatefulTimeout@PreDestroy
R to PThe EJB container passivates idle beans and removes them from active memory based on specific algorithms@PrePassivate
P to DNEThe bean reaches idle time out threshold designated by DD or @StatefulTimeoutNote: @PreDestroy annotated method is NOT invoked
P to RWhen 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.

package com.abhirockzz.wordpress.ejb.lifecycle.stateful;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateful;

@Stateful
public class MyStatefulBean {

    public MyStatefulBean() {
    }

    public void act() {
        System.out.println("Entered MyStatefulBean/act() on " + new Date().toString() + " . SFSB instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(MyStatefulBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Exit MyStatefulBean/act() on " + new Date().toString() + " . SFSB instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());

    }
}
package com.abhirockzz.wordpress.ejb.lifecycle.stateful;

import java.io.IOException;
import java.util.Date;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "SFSBTestServlet", urlPatterns = {"/SFSBTestServlet"})
public class SFSBTestServlet extends HttpServlet {

    public SFSBTestServlet() {
    }

    @Inject
    MyStatefulBean mySFSB;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("Entered SFSBTestServlet/doGet() on " + new Date().toString() + " . Servlet instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());
        mySFSB.act();
    }

}

 

HTTP GET request via JMeter

HTTP GET request via JMeter

Concurrent request simulation via JMeter

Concurrent request simulation via JMeter

 

Observations

  • 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

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 one!

package com.abhirockzz.wordpress.ejb.lifecycle.stateless;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;

@Stateless
public class MyStatelesslBean {

    public void act() {

        System.out.println("Entered MyStatelesslBean/act() on " + new Date().toString() + " . SLSB instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(MyStatelesslBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Exit MyStatelesslBean/act() on " + new Date().toString() + " . SLSB instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());
    }
}
package com.abhirockzz.wordpress.ejb.lifecycle.stateless;

import java.io.IOException;
import java.util.Date;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "SLSBTestServlet", urlPatterns = {"/SLSBTestServlet"})
public class SLSBTestServlet extends HttpServlet {

    @Inject
    MyStatelesslBean slsb;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("Entered SLSBTestServlet/doGet() on " + new Date().toString() + " . Servlet instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());

        slsb.act();

    }

}

 

Observations

  • Since a Servlet itself is not thread safe, multiple threads will in fact enter the doGet() method
  • Different instances of the SLSB (evident via the hashCode result) are being picked by the container to manage concurrent requests (see the thread names in the logged statements).
  • In spite of concurrent requests, each request thread is getting serviced by a new instance
Console logs

Console logs

That’s all for now! I am planning to cover Singleton Session beans in a future post. Stay tuned . . . .

Thanks for reading!

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


four − 1 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close