About Question enthuware.jwpv6.2.626 :
Posted: Wed Aug 28, 2013 10:39 am
I am not clear how the UserInfo bean can ensure Thread safety. The calling servlet should have this responsibility. Please explain how the bean can do so.
Java Certification Resources and Java Discussion Forum
https://enthuware.com/forum/
This has nothing to do with the servlet specification. This is about regular java programming. If you want to make a class thread safe, you have to code that particular class as thread safe. You can't depend on other classes that access the target class to access it in a thread safe manner.mtmmjava wrote:Hi
where in the specs can I find statements that support option 2 instead of option 5?
Both the questions are different. In 2.727, it is explicitly given that the session is not accessed from anywhere else other than the given code. Further, it is only asking you to make sure that session is consistent in that particular situation. Not for all the situations.[edit] Further info: you say option 5 is wrong because this responsibility cannot be put on servlets. But on question enthuware.jwpv6.2.727 you accept putting synchronized blocks on the servlet (synchronizing the session object) as the correct approach to achieve the same goal.
thanks.
Code: Select all
//psuedo code for one of the servlets
public class ServletA extends HttpServlet{
public void doGet (HttpServletRequest request, HttpServletResponse response) {
HttpSession s = request.getSession();
synchronize (s){
//code access UserInfo
}
}
}
Code: Select all
public class ServletA extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
{
HttpSession s = request.getSession();
System.out.println("Session ID servlet A : "+ s.getId());
UserInfo userInfo = new UserInfo();
s.setAttribute("UserInfo", userInfo);
synchronized (s){
System.out.println("Start synchronize s in A,current start Time in A at : "+System.currentTimeMillis());
UserInfo user = (UserInfo) s.getAttribute("UserInfo");
Thread t = new Thread(user) ;
t.start();
System.out.println("Current end time in A and dispatch to B at : "+ System.currentTimeMillis());
request.getRequestDispatcher("/ServletB").forward(request, response);
}
}
Code: Select all
public class ServletB extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession s = request.getSession();
System.out.println("Session ID servlet B : "+ s.getId());
synchronized (s){
System.out.println("Start synchronize s in B ,current start Time in B at:" +System.currentTimeMillis());
UserInfo user = (UserInfo) s.getAttribute("UserInfo");
Thread t = new Thread(user);
t.start();
System.out.println("Current end time in B at : "+ System.currentTimeMillis());
}
}
}
Code: Select all
public class UserInfo implements Runnable{
public void doTasks(){
System.out.println(this.toString()+" starts task at " + System.currentTimeMillis() );
try{
Thread.sleep(10000);
}
catch(InterruptedException e){e.printStackTrace();}
System.out.println(this.toString()+" ends task at " + System.currentTimeMillis());
}
@Override
public void run() {
doTasks();
}
}
Session ID servlet A : 4F452130F3CD73DE089F0F28746BCD20
Start synchronize s in A,current start Time in A at : 1463880927245 (locking session starts here)
Current end time in A and dispatch to B at : 1463880927246
com.nullhaus.UserInfo@65400e52 starts task at 1463880927248 (after 3 ms, access userInfo)
Session ID servlet B : 4F452130F3CD73DE089F0F28746BCD20
Start synchronize s in B ,current start Time in B at:1463880927257 (after 12 ms, locking session again)
Current end time in B at : 1463880927258
com.nullhaus.UserInfo@65400e52 starts task at 1463880927260
com.nullhaus.UserInfo@65400e52 ends task at 1463880937249
com.nullhaus.UserInfo@65400e52 ends task at 1463880937261
Code: Select all
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession s = request.getSession();
System.out.println("Session ID servlet A : "+ s.getId());
UserInfo userInfo = new UserInfo();
s.setAttribute("UserInfo", userInfo);
System.out.println("current start Time in A at : "+System.currentTimeMillis());
UserInfo user = (UserInfo) s.getAttribute("UserInfo");
Thread t = new Thread(user) ;
t.start(); //While this thread is running, the request is dispatched to servlet B.
//Servlet B will wait until it gets the lock of s.
System.out.println("Current end time in A and dispatch to B at : "+ System.currentTimeMillis());
request.getRequestDispatcher("/ServletB").forward(request, response);
}
}
Code: Select all
public class ServletB extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession s = request.getSession();
System.out.println("Session ID servlet B : "+ s.getId());
System.out.println("current start Time in B at:" +System.currentTimeMillis());
UserInfo user = (UserInfo) s.getAttribute("UserInfo");
Thread t = new Thread(user);
t.start();
System.out.println("Current end time in B at : "+ System.currentTimeMillis());
}
}
Notes about this example :Session ID servlet A : 4F452130F3CD73DE089F0F28746BCD20
current start Time in A at : 1463883713407 ( servlet A starts here)
Current end time in A and dispatch to B at : 1463883713407
Session ID servlet B : 4F452130F3CD73DE089F0F28746BCD20
current start Time in B at:1463883713424 ( after 17 ms , servlet B starts here)
Current end time in B at : 1463883713424
com.nullhaus.UserInfo@1763df61 starts task at 1463883713424 (after 17 ms, A or B accesses UserInfo)
com.nullhaus.UserInfo@1763df61 starts task at 1463883713424 (after 17 ms, A or B access UserInfo)
com.nullhaus.UserInfo@1763df61 ends task at 1463883723424
com.nullhaus.UserInfo@1763df61 ends task at 1463883723425