- The application container can pool instances of stateless session beans to increase performance.
- When the client requests an operation on the bean, the container can assign an available instance from the pool reducing instance creation overhead.
- After completion the bean is either returned to the pool or destroyed.
It should be noted that the same client can get different bean instances on different invocations. In the below example, bean ‘A’ has 4 instances pooled A1 to A4. Client 1 on 1st invocation gets A1 whereas on next invocation it gets A2 bean instance.
Similarly different clients may get same instance (but not at the same time). For example, Client 3 may get A3 instance and after completion, Client 4’s request may also be assigned A3.
Example
We create an AccountBean with two instance variables ‘name’ and ‘balance’. We show that the container can assign any instance from the pool to any client or multiple invocation of same client.
Business Interface
Create a business interface either Remote or Local
package com.ibytecode.business; import javax.ejb.Remote; @Remote public interface Account { void deposit(double amount); String printAccountDetails(); public String getName(); public void setName(String name); public double getBalance(); public void setBalance(double balance); }
Bean Implementation Class
Create the bean implementation class.
package com.ibytecode.businesslogic; import com.ibytecode.business.Account; import javax.ejb.Stateless; @Stateless public class AccountBean implements Account { private String name = "Default"; private double balance = 50; public AccountBean() {} public void deposit(double amount) { balance = balance + amount; } public String printAccountDetails() { return "Account [name=" + name + ", balance=" + balance + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } }
Java Application Client.
package com.ibytecode.client; import javax.naming.Context; import javax.naming.NamingException; import com.ibytecode.business.Account; import com.ibytecode.businesslogic.AccountBean; public class AccountBeanClient implements Runnable{ public static void main(String[] args) { AccountBeanClient obj1 = new AccountBeanClient(); for(int i = 0 ; i < 10; i++) { Thread t1 = new Thread(obj1, "T" + i); t1.start(); } } public void run() { Account bean = doLookup(); // 1. Setting name and balance bean.setName(Thread.currentThread().getName()); bean.setBalance(Math.ceil(Math.random() * 10000)); // 1. Reading the state of the bean for the first time System.out.println(Thread.currentThread().getName() + " -> Reading Name : " + bean.getName()); System.out.println(Thread.currentThread().getName() + " -> Reading Balance : " + bean.getBalance()); System.out.println(Thread.currentThread().getName() + " " + bean.printAccountDetails()); } //JNDI Lookup differs based on different containers private static Account doLookup() { //Refer the example link for complete code . . . . } }
- We create 10 threads (with names T0 – T9) which requests access to the bean and its operations.
- The container for each of the requests from same or different client assigns instances randomly from the pool which can be seen in the below output.
T0 -> Reading Name : T2
T3 -> Reading Name : T0
T5 -> Reading Name : T7
T2 -> Reading Name : T9
T9 -> Reading Name : T6
T8 -> Reading Name : T8
T6 -> Reading Name : T3
T1 -> Reading Name : T6
T4 -> Reading Name : T4
T5 -> Reading Balance : 7114.0
T2 -> Reading Balance : 1360.0
T7 -> Reading Name : T2
T3 -> Reading Balance : 4104.0
T9 -> Reading Balance : 3957.0
T8 -> Reading Balance : 8883.0
T6 -> Reading Balance : 6166.0
T1 -> Reading Balance : 7114.0
T5 Account [name=T2, balance=3112.0]
T2 Account [name=T0, balance=1360.0]
T0 -> Reading Balance : 9568.0
T7 -> Reading Balance : 3957.0
T3 Account [name=T9, balance=4104.0]
T9 Account [name=T3, balance=8883.0]
T4 -> Reading Balance : 6166.0
T8 Account [name=T6, balance=9568.0]
T1 Account [name=T2, balance=3112.0]
T7 Account [name=T7, balance=3957.0]
T6 Account [name=T8, balance=7114.0]
T0 Account [name=T0, balance=1360.0]
T4 Account [name=T9, balance=4104.0]
- The thread T0 on operations getName(), getBalance() and printAccountDetails() gives different results because different instances are assigned on each invocation.
T0 -> Reading Name : T2
T0 -> Reading Balance : 9568.0
T0 Account [name=T0, balance=1360.0]