@WebServlet(name = "MyAsyncServlet", urlPatterns = {"/MyAsyncServlet"} , asyncSupported=true)
public class MyAsyncServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
final AsyncContext ac = request.startAsync();
final HttpServletRequest localRequest = request;
//Attribute default_Age being set in the main thread of the servlet
localRequest.setAttribute("default_Age", "18");
System.out.println("Default age being set in the main thread: "+ (String)localRequest.getAttribute("default_Age"));
ac.start(new Runnable() {
public void run(){
//Attribute default_Age being set in another thread.
localRequest.setAttribute("default_Age","20");
System.out.println("Default age being set in the thread : "+(String)localRequest.getAttribute("default_Age"));
}
});
//This default age result is unexpected either 18 or 20.
//If the runnable thread runs after the main thread, it will be 20.
//If the main thread runs before the runnable thread , it will be 18.
System.out.println(" final default age : "+ (String)localRequest.getAttribute("default_Age"));
ac.complete();
}
}
Possible result:
Default age being set in the main thread: 18
final default age : 18
Default age being set in the thread : 20
Can this code example demonstrate the request object is not thread safe ?
The code does show that request object is not thread safe. However, you are not allowed to create threads in a servlet. Servlet container cannot guarantee thread safely if you violate its conditions.
-Paul.
If you like our products and services, please help us by posting your review here.
Hi, Paul. Thanks for your reply.
So, I can first create a separate class which implements Runnable.
Then, I instantiate an instance of this class and pass it to AsyncContext.start() method as an argument?
package com.nullhaus;
....
@WebServlet(name = "AsyncServlet1", urlPatterns = {"/AsyncServlet1"} , asyncSupported=true)
public class AsyncServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
final AsyncContext ac = request.startAsync();
final HttpServletRequest localRequest = request;
localRequest.setAttribute("default_Age", "18");
System.out.println("Default age being set in the main thread: "+ (String)localRequest.getAttribute("default_Age"));
ThreadPoolExecutor executor = (ThreadPoolExecutor)request.getServletContext().getAttribute("executor");
executor.execute( new MyRunnable(ac,localRequest));
System.out.println(" final default age : "+ (String)localRequest.getAttribute("default_Age"));
}
}
package com.nullhaus;
...
public class MyRunnable implements Runnable{
private HttpServletRequest localRequest ;
private AsyncContext asyncCtx;
public MyRunnable(){}
public MyRunnable(AsyncContext asyncCtx, HttpServletRequest req){
this.asyncCtx = asyncCtx;
this.localRequest=req;
}
@Override
public void run() {
localRequest.setAttribute("default_Age","20");
System.out.println("Default age being set in MyRunnable thread : "+(String)localRequest.getAttribute("default_Age"));
asyncCtx.complete();
}
}