About Question enthuware.jwpv6.2.626 :

Moderator: admin

Post Reply
PMiglani
Posts: 14
Joined: Sat Jan 19, 2013 8:42 am
Contact:

About Question enthuware.jwpv6.2.626 :

Post by PMiglani »

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.

admin
Site Admin
Posts: 10058
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.jwpv6.2.626 :

Post by admin »

Option 1 describes one way in which the UserInfo bean can ensure thread safety. Although the option itself is wrong because it says "must" but it is nevertheless a valid approach.


HTH,
Paul.
If you like our products and services, please help us by posting your review here.

mtmmjava
Posts: 9
Joined: Mon Nov 04, 2013 7:49 am
Contact:

Re: About Question enthuware.jwpv6.2.626 :

Post by mtmmjava »

Hi
where in the specs can I find statements that support option 2 instead of option 5?
[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.

admin
Site Admin
Posts: 10058
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.jwpv6.2.626 :

Post by admin »

Hi,
mtmmjava wrote:Hi
where in the specs can I find statements that support option 2 instead of option 5?
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.
[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.
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.

While in 2.626, it is asking you to ensure thread safety of UserInfo in general and not in a specific situation. It doesn't say anything about what all servlets this object is being accessed. Therefore, the right approach in this case is to make the UserInfo thread safe instead of giving the responsibility of thread safety to the servlets.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

himaiMinh
Posts: 358
Joined: Fri Nov 29, 2013 8:26 pm
Contact:

Re: About Question enthuware.jwpv6.2.626 :

Post by himaiMinh »

Hi,
Is it feasible for all servlets to synchronize the session like this ?

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

      }

  }

}



himaiMinh
Posts: 358
Joined: Fri Nov 29, 2013 8:26 pm
Contact:

Re: About Question enthuware.jwpv6.2.626 :

Post by himaiMinh »

My Demo for option 5:

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
Last edited by himaiMinh on Sat May 21, 2016 9:32 pm, edited 1 time in total.

himaiMinh
Posts: 358
Joined: Fri Nov 29, 2013 8:26 pm
Contact:

Re: About Question enthuware.jwpv6.2.626 :

Post by himaiMinh »

Demo without session synchronization:

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());
         
     }
 }
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
Notes about this example :
1. with session synchronization, Servlet A locks the session object at time = 0. Then, Servlet B locks the session object after 12 ms .

2. without session synchronization, Servlet A and B access UserInfo at the same time and ends at about the same time.
Last edited by himaiMinh on Sat May 21, 2016 9:33 pm, edited 1 time in total.

himaiMinh
Posts: 358
Joined: Fri Nov 29, 2013 8:26 pm
Contact:

Re: About Question enthuware.jwpv6.2.626 :

Post by himaiMinh »

My final conclusion is :
Is option 5 , is letting the servlet to synchronize the session a good solution?

admin
Site Admin
Posts: 10058
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.jwpv6.2.626 :

Post by admin »

It will work only if where ever you retrieve session, you synchronize on the session. Not just in servlets, but also in JSPs, custom tags, filters etc. If someone forgets to do it, everything will be messed up. So I don't think it is a good solution in that respect.

-Paul.
If you like our products and services, please help us by posting your review here.

Post Reply

Who is online

Users browsing this forum: No registered users and 24 guests