Heap Generation In Java Spring Autowiring
Use of Asynchronous Servlet Specification
Use of Asynchronous Servlet Specification
The most basic motivation for asynchronicity in web applications is to handle requests that take longer to complete — possibly running a slow database query, making calls to external REST APIs, or performing other I/O-bound operations. Such requests can quickly exhaust the Servlet container thread pool and affect scalability.
In some cases you may not necessarily have to wait for the processing to complete, e.g. sending an email, kicking off a database job, etc. For such fire-and-forget scenarios you can use servlet's @Async support or place an event and return immediately, possibly including a confirmation id with the response for later use.
For other cases where the result is required before returning, you'll need a way to decouple request processing from the Servlet container thread in order to improve scalability. To enable this Servlet 3 allows a Servlet to indicate it wants to leave the response open after it has returned so that the request may be completed from a separate thread.
To achieve that the web application can call request.startAsync() and use the returned AsyncContext to continue to write to the response (and eventually finalize it) from a separate thread. From a client's perspective nothing has changed. The request still looks like any other request with standard HTTP request-response semantics.
Below is an example for using asynchronous servlet 3.0 where I am using servlet to accept some parameters from a client and create the POJO'S class object corresponding to it then spool or stored it to a location and then my asynchcronous task is used to insert it into the database(using hibernate version 4).
/*
author:Ishant Agarwal
date:16th july 2012
*/
package com.java.asynch;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.sql.PreparedStatement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.math.RandomUtils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
@WebServlet(urlPatterns = "/AsyncDispatcherServlet",asyncSupported=true)
public class AsyncDispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final int NUM_ASYNC_TASKS = 100;
private ExecutorService exececutor;
private SessionFactory sessionFactory ;
@Override
public void init() throws ServletException {
super.init();
exececutor = Executors.newFixedThreadPool(NUM_ASYNC_TASKS) ;
}
@Override
public void destroy() {
exececutor.shutdownNow() ;
super.destroy();
}
public AsyncDispatcherServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
String name = request.getParameter("name") ;
int age = Integer.parseInt(request.getParameter("age")) ;
int salary = Integer.parseInt(request.getParameter("salary")) ;
String designation = request.getParameter("designation") ;
boolean isMarried = Boolean.parseBoolean(request.getParameter("ismarried")) ;
long transactionID = RandomUtils.nextInt();
final Employee emp = new Employee();
emp.setTransactionId(transactionID) ;
emp.setAge(age) ;
emp.setName(name) ;
emp.setSalary(salary) ;
emp.setDesignation(designation) ;
emp.setMarried(isMarried) ;
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/spool/" + transactionID));
oos.writeObject(emp) ;
oos.flush() ;
oos.close() ;
final AsyncContext asynchctx = request.startAsync() ;
asynchctx.setTimeout(100) ;
@SuppressWarnings("unchecked")
FutureTask task =new FutureTask(new Runnable() {
public synchronized void run() {
synchronized (asynchctx) {
try{
Session session = sessionFactory.openSession() ;
Transaction tx = session.beginTransaction() ;
tx.commit() ;
File f= new File("D:/spool/"+emp.getTransactionId()) ;
System.out.println("isFileDeleted:" + f.delete()) ;
session.close() ;
}catch(Exception ex){
ex.printStackTrace() ;
}
}
}
},null) ;
asynchctx.addListener(new SimpleAsyncListener()) ;
exececutor.execute(task) ;
asynchctx.complete() ;
System.out.println("Task successfully completed");
}
}
package com.java.asynch;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil {
private static ServiceRegistry serviceRegistry;
private static final SessionFactory sessionFactory;
static {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
package com.lumata.asynch;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
/*@Table(name="employee",uniqueConstraints={@UniqueConstraint(columnNames="TransactionId")})*/
@Table(name="employee")
public class Employee implements Serializable{
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + ", isMarried="
+ isMarried + ", designation=" + designation + ", salary=" + salary + ", ID=" + id
+ "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (id != other.id)
return false;
return true;
}
String name ;
Long id ;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="Id",unique=true,nullable=false)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
Long transactionId ;
@Column(name="TransactionId",nullable=false)
public Long getTransactionId() {
return transactionId;
}
public void setTransactionId(Long transactionId) {
this.transactionId = transactionId;
}
@Column(name="name",nullable=false,length=20)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="age",nullable=true)
public Integer getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Column(name="ismarried",nullable=true)
public boolean isMarried() {
return isMarried;
}
public void setMarried(boolean isMarried) {
this.isMarried = isMarried;
}
@Column(name="designation",length=10,nullable=true)
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
@Column(name="salary",nullable=true)
public Integer getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
int age ;
boolean isMarried ;
String designation ;
int salary ;
}
package com.java.asynch;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
public class SimpleAsyncListener implements AsyncListener{
SimpleAsyncListener(){
super() ;
}
@Override
public void onStartAsync(AsyncEvent ae) {
System.out.println("AsyncListener: onStartAsync" + ae.getAsyncContext().getRequest().isAsyncStarted());
}
@Override
public void onComplete(AsyncEvent ae) {
System.out.println("task completed");
}
@Override
public void onTimeout(AsyncEvent ae) {
System.out.println("AsyncListener: onTimeout for request: " +
ae.getAsyncContext().getRequest().getParameter("id"));
}
@Override
public void onError(AsyncEvent ae) {
Employee emp = (Employee)ae.getAsyncContext().getRequest().getAttribute("emp") ;
System.out.println("Eror employees Id" + emp) ;
}
}
From a server perspective however, async processing has enabled the handling of requests in a more scalable fashion. The following is the sequence of events one more time:
1)Client sends a request
2)Servlet container invokes a servlet (also allocating a thread)
3)The servlet calls request.startAsync(), saves the AsyncContext, and returns
4)The container thread is released but the response remains open
5)Another thread uses the saved AsyncContext to complete the response
6)Client receives the response
For heap generation and garbage collection click on below given link
http://agrawalishant.blogspot.in/2012/08/heap-generation-and-garbage-collection.html