Announcement Announcement Module
Collapse
No announcement yet.
Issues with multithreading and controllers? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Issues with multithreading and controllers?

    If I understand the Spring lifecycle, at least semi-correctly, then each singleton bean in my config file (or files) is instantiated once at startup and that same instance is supplied any time the bean is requested. It seems like there should be all kinds of issues with the controller beans (and any other singleton beans, for that matter) being used in multiple threads, especially in a web application, yet I haven't seen this issue discussed anywhere.

    Do I need to avoid instance variables in my singleton beans (esp controllers), or at least synchronize access to them? It seems like not using instance variables is probably the best way to go in any case, at least with controllers. Come to think of it, most of my Spring-managed beans don't have much use for instance variables in any case...

    Along the same lines, shouldn't the controller methods be synchronized to prevent multiple threads from messing with local variables?

    I'm sure I'm missing something here - I'm not very familiar with threading issues in general. If anyone could shed some light on the issues, particularly in a web application, with controller and singleton beans and multithreading I would really appreciate it! Thanks in advance!

    Brian St.Clair

  • #2
    Re: Issues with multithreading and controllers?

    Originally posted by brianstclair
    Along the same lines, shouldn't the controller methods be synchronized to prevent multiple threads from messing with local variables?
    A spring Controller runs inside a Servlet and a Servlet is multi-threaded by default. This means that many requests could be handled by the same Controller simultaneously.

    Read up about the Servlet threading model. The same applies to stuff running inside the servlet.

    S.

    Comment


    • #3
      Which is exactly my point. Many requests are handled by the same controller - multiple threads accessing it, but the same instance being accessed. Doesn't that come back to the basic issue of multithreading and synchronization? For example, if there were an instance variable inside a controller, couldn't the multiple threads independently modify that variable at unpredictable times and cause problems for other threads? Hope what I just said was clear, and thanks for the response Stefan.

      Brian

      Comment


      • #4
        I guess the key to understanding this is that every thread has its own stack.

        Comment


        • #5
          Originally posted by brianstclair
          Doesn't that come back to the basic issue of multithreading and synchronization? For example, if there were an instance variable inside a controller, couldn't the multiple threads independently modify that variable at unpredictable times and cause problems for other threads?

          Brian
          Everything you say is true but your assumption that synchronization is the only solution is not. The other solution is not to use instance variables which as far as I understand is the assumption with controllers.

          Comment


          • #6
            To the creator of the topic: just use HttpSession or Request Attributes (session scope and request scope variables respectively) instead of controller's instance variables for your needs.

            Comment


            • #7
              Thanks to all who replied - greatly appreciated!

              Brian

              Comment


              • #8
                multithreading in struts,tiles and spring

                Since servlet is multithreaded and we use Tiles Spring based delegator controller, what is the problem in using instance variables in action classes which are spring beans(not defined as singleton=false in configuration)? Per request, there is a seperate instance of servlet, and stack of spring beans is used. But we need the information to be persisted between the method calls for each request. I do not see multithreading problems here. But recently Fortify complained about this.
                Is there anything wrong with my assumption?

                Comment


                • #9
                  Hi,

                  How about using ThreadLocal Variables i.e. for each thread it will create its own independent copy? Just incase its required that each thread has some kind of static variable at the thread level.

                  -Hetal

                  Comment


                  • #10
                    @vkotian: No, every request is handled by the same instance! Instance variables are bad, unless they are thread-safe like stateless services, constants etc.

                    @Hetal B: Thread-local variables only work per request. So creating method-scoped variables in the request handling method and passing them around has the same effect and is IMHO less opaque.
                    Just my 0.02€

                    Comment


                    • #11
                      @vkotian: Like F.Degenaar said, instance variables are bad. If you need to persist the data across multiple requests then you should either store that data in the session or persist it to a database.

                      Comment


                      • #12
                        @F.Degenaar: rules are meant to be broken. for every request, if there is a new servlet instance, then that means new action instance as per spring delegator. So, for each request, there is new servlet instace with new action instance. now where is the instance variable issue? if u r talking about context switch happening during the method call, still the method calls are happening in 2 different objects. the objects are sane to have their instance variables. can someone explain if this is not correct.
                        Spring guys,tell me, do I have to specifically say to the bean singleton=false?

                        Comment


                        • #13
                          Controllers should be singletons. They should NOT have state. They are shared across multiple threads.

                          If your user needs conversations state, this data should be stored in the session object not in the controller. Form objects are a different beast entirely. They only exist for the current request/response cycle.

                          Comment


                          • #14
                            @vkotian: There is no new servlet instance for every request. This would make Java web applications inherently unscalable, if you think about it for a moment. Even synchronized access of a servlet instance is deprecated nowadays: http://java.sun.com/javaee/5/docs/ap...readModel.html.
                            Bottom line: Don't use stateful instance variables.

                            Comment


                            • #15
                              some code

                              Let me put some code here.

                              public class SingletonClass{
                              private static SingletonClass _instance=null;

                              public int IsItThreadSafeMethod(int i) throws Exception{
                              int j=i;
                              Thread.sleep(1000);
                              return j;
                              }
                              private SingletonClass(){
                              }
                              public static SingletonClass getInstance(){
                              if(_instance==null) _instance=new SingletonClass();
                              return _instance;
                              }

                              }
                              Now when multiple threads get the same SingletonClass object, they will try to invoke the same method with different int values.
                              System.out.println(SingletonClass.getInstance().is ItThreadSafeMethod(1));
                              System.out.println(SingletonClass.getInstance().is ItThreadSafeMethod(2));
                              System.out.println(SingletonClass.getInstance().is ItThreadSafeMethod(3));

                              Here is the test class.
                              public class ThreadingSingletons implements Runnable{
                              private int id=-1;
                              public void run(){
                              try{
                              //System.out.println(SingletonClass.getInstance().Is ItThreadSafeMethod(id));
                              if(SingletonClass.getInstance().IsItThreadSafeMeth od(id)==id){
                              //System.out.println("Test Passed");
                              }else{
                              System.out.println("Test failed!Exiting...");
                              }
                              }catch(Exception e){
                              System.out.println("Some Problem. Exception thrown");
                              }
                              }
                              public ThreadingSingletons(int id){
                              this.id=id;
                              }
                              public static void main(String[] s){
                              for(int i=0;;i++){
                              new Thread(new ThreadingSingletons(i)).start();
                              //to avoid integer out of bounds
                              if(i==5000) i=0;
                              }
                              }

                              }

                              I did not find 'test failed' message till now.
                              That means if instance variables not used,method is really thread safe.
                              Why I am putting this here bcoz, in Spring, we need not put singleton=false for such classes which do not have instance variables or class variables.
                              Is this assumption correct?
                              Let me know.
                              Let me give some more introduction here. I am trying here to delegate all the work to service layer, by introducing spring, since it gives more flexibility to test the service layer, independently. this is jdk1.4 code. My concern was that, if there is a method with arguments but, not using any instance variables, when there are dual core or multi core CPUs executing this code, will it cause any problems due to context switching. Remember singleton object is passed.
                              Let me know.

                              Comment

                              Working...
                              X