Announcement Announcement Module
Collapse
No announcement yet.
Do I need things to be synchronized? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Do I need things to be synchronized?

    I have a class that works in the following way: I set the information in the class to be used and then call a function that produces information based on the state of the class or information I provided it. Here is a very simple example (this is not the actual class, but works the same way)

    Code:
    class Adder
    {
       private int num1;
       private int num2;
    
       public void setNum1(int num1)...
       public int getNum1()...
    	
       public void setNum2(int num2)...
       public int getNum2()...
    
       public int add()
       {
          return num1 + num2;
       }
    }
    If I register this as a Spring bean, is there going to be a concurrency issue? Say for instance, two request are made to set num1 and num2 and then another request changes the values before the first request calls add(), the first requester is going to get an unexpected value, correct? Does Spring handle issues like this automatically or do I need to mark the variables as synchronized? Thank you.

    --JDS

  • #2
    Normally I wouldn't suggest to make things synchronized. Try to make your class thread-safe and if you do need to keep state, make it a prototype or pool it (if it is expensive to create an instance of the class--because of resources that take long to initialize).

    Strategies and templates generally allow for a more thread-safe way to design your components, this is what Spring uses a lot as well.

    I think I don't have to point out that in this (probably not so realistic) example you could just as well implement it as add(int one, int two) { return one + two; }.

    Maybe you can elaborate a bit on what the specific use case would be?

    Comment


    • #3
      Let me see if I can give you a more specific reason why I modeled my classes this way.

      I have a class that is designed to compute a lot of calculations. Looks something like this:

      Code:
      public class Example
      {
          List exampleNumbers1;
          List exampleNumbers2;
          List exampleNumbers3;
      
          public void setup(List moreInformation) ...
          public List calculate() ...
      
          private int figureSomethingOut1() ...
          private boolean figureSomethingOut2() ...
      }
      Again, this is a contrived example because I can't specifically publish this class, but the basic idea is there. Anyway, the point is that the private methods in the class are needed to figure out arbitrary things about exampleNumbers1, exampleNumbers2, and exampleNumbers3 when the calculate method is called. Also, more information is pulled out of database in setup(). An example of the usage of this class would be like this (assuming it's registered as a Spring bean named calculator)...

      Code:
      List l = getLatestNumbers();
      calculator.setup(l); // feed the information
      List results = calculator.calculate(); // calculate based on what was given in setup
      So the Spring bean holds the state in order for me to call all the methods successfully. If you can understand what I'm trying to do, is there another way to implement this so that I do not run into this problem? I do realize that this problem wouldn't exist if I called everything in one method (like calculate() for instance), but that's just too ugly. Maybe if I broke this thing down into separate layers, I would have what I'm trying to accomplish -- no concurrency issues. Is my example a little bit better? Thanks for the reply, by the way.


      --JDS

      Comment


      • #4
        Why do you want to retrieve this "calculator" object from a BeanFactory? Is there some complex setup that it requires? or some dependencies it needs injected? It's dificult to know your requierments without a better example.

        One thing that's for sure is that a statefull class like the one you've described is not going to be safe for use in more than one thread at a time. There's nothing wrong with this kind of class just as long as you get a new instance each time you want to use it.

        Ollie

        Comment


        • #5
          Originally posted by oliverhutchison
          Why do you want to retrieve this "calculator" object from a BeanFactory? Is there some complex setup that it requires? or some dependencies it needs injected? It's dificult to know your requierments without a better example.
          No, I don't want to retrieve any object from a BeanFactory. I meant that to be an example of how I use the two public methods, calculate(), setup(), and the relationship between them. I aplogize for these horribly contrived examples. There is a complex setup, I suppose. Meaning that I need to extract a lot of information from the database in order to do the calculations. That's part of the problem.

          Although my examples are bad, they illustrate the problem. I'm using the class to hold class-wide data and the methods in that class are making calculations based on that data. Unless I can figure out how to rewrite the class to avoid the concurrency problem, I suppose the next best thing is to NOT register the bean as a singleton and make sure a different instance is created each time it is used. I didn't want to do this because I figured it would lead to bad performance. However, I haven't yet tried it out to see how it would affect performance.

          Comment


          • #6
            If your "calculator" object is statefull then there's no easy way to avoid the concurrency problem.

            If enough of the data in "calculator" is immutable it would make sense to extract it into a data holder singleton that is then referred to by each new calculator instance. Hopefully the expensive database lookup would only need to be done once for the data holder and the calculators could be cheaply instantiated and then thrown away.

            Ollie

            Comment


            • #7
              Originally posted by oliverhutchison
              If your "calculator" object is statefull then there's no easy way to avoid the concurrency problem.

              If enough of the data in "calculator" is immutable it would make sense to extract it into a data holder singleton that is then referred to by each new calculator instance. Hopefully the expensive database lookup would only need to be done once for the data holder and the calculators could be cheaply instantiated and then thrown away.
              Ok, thanks. I'll just change it to non-singleton. Which brings me to one more question...Do I have to destroy the object after I'm done using it (i.e. set it to null) or does the container do that?

              --JDS

              Comment


              • #8
                A Spring bean factory generates POJOs there's no special processing required.

                Comment


                • #9
                  Thanks oliverhutchison! You've been very helpful.

                  Originally posted by oliverhutchison
                  A Spring bean factory generates POJOs there's no special processing required.
                  So everytime I make a reference to my Spring bean that is NOT configured to be a singleton, Spring creates a new instance of it, performs the operations, and destroys it when necessary? Or I guess I should say, marks it to be destroyed.

                  Ok, I think I got it. Thanks again!

                  --JDS

                  Comment


                  • #10
                    So everytime I make a reference to my Spring bean that is NOT configured to be a singleton, Spring creates a new instance of it, performs the operations, and destroys it when necessary? Or I guess I should say, marks it to be destroyed.
                    For prototype beans Spring creates a new instance each time you call beanFactory.getBean() and that is all it does. There is no need to destroy the beans once they are no longer reachable they'll be garbage collected.

                    Comment

                    Working...
                    X