Spring MVC Singleton Thread Security?

I have a singleton Spring bean (default scope). Thus, one instance will be used by several threads. However, I am a bit confused about thread safety, it is obvious that all Spring beans are thread safe if they have no state, but my bean is not stateless, it has different instance variables that are used by each request / other controllers / classes.

Here is the beginning of my singleton bean:

public class PcrfSimulator { private final CustomGxSessionIdCacheImpl gxSessionIdCache = new CustomGxSessionIdCacheImpl(); private final PcrfRecord pcrfRec = new PcrfRecord(); private final ResponseConditions responseConditions = new ResponseConditions(); public CustomGxSessionIdCacheImpl getGxSessionIdCache() { return gxSessionIdCache; } public ArrayList<Rule> getRules() { return pcrfRec.getRules(); } 

Thus, several threads will be available to the fields above - is it enough to mark these fields as mutable, or do I need to mark the methods that they access (there are many not only this class, but also other controllers / classes) with synchronization and using wait / notify etc.

Many thanks!

+6
source share
4 answers

volatile does not help. It will only make sure that the value is really updated.

Volatile means (http://www.javamex.com/tutorials/synchronization_volatile.shtml):

  • The value of this variable will never be cached by the thread-locally: all reads and writes will go directly to the "main memory";
  • Access to a variable acts as if it were enclosed in a synchronized block synchronized by itself.

Method synchronization will only help if your control flow never leaves the (external) synchronized block between the first record and the last read for shared variables, and all shared variables are only available in synchronized blocks that use the same object lock.

Thus, a common solution is to prevent common variables in this scenario. One simple way to make a class immutable is to use local variables and method parameters instead of generic instance variables.


You wrote: "Spring beans are thread safe if they have no state, but my bean is not stateless." - It is good that the topic is discussed in the paragraph above.

But from your code these are the seams that this is not a problem! Variables marked with the final sign are therefore immutable. If the fields of this object behave the same way (they are not updated or are not protected from problems with simultaneous modification), you do not have the shared variables changed. This is sometimes called "stateless effective . " This means that the values ​​do not change. So this is not a problem for concurrency (because the concurrency problem is related to changing values).

In the end: you can use this efficient class without saving the state from the example in different threads without a synchronized block if the fields ( PcrfRecord ...) are effective without attacks. (If the fields PcrfRecord ... are not stateless, then the PcrfSimulator class cannot be called effective non-state). But this has to do with Spring, it is simple Java.

Btw: if your variable is final , you do not need to make them volantile .

+3
source

Spring itself will definitely publish your beans after it has been instantiated, injected, etc. This means that any thread that has a link to your singleton bean will at least see its state, as it was at the end of creating the Spring context.

If the condition is unchanged, you have nothing to do.

If the singleton state is changed, you will have to correctly synchronize calls to this mutable state.

+3
source

Your class will not be thread safe if you mark it as singleton in the context, since you initialize the fields with " new " manually, which happen once when the bean is created, and you will have one instance in memory, such as your singleton, and accordingly your threads share an instance of CustomGxSessionIdCacheImpl, PcrfRecord, etc.

If you can get these instances to take control of the spring context, for example:

 <bean id="customGxSessionIdCache" class="package.CustomGxSessionIdCacheImpl" scope="prototype"> 

and open them in PcrfSimulator, for example:

 @Autowired private final CustomGxSessionIdCacheImpl gxSessionIdCache 

after that, as soon as you access the code in gxSessionIdCache, spring creates a new instance for each access and for each thread, respectively. Any other methods in Singleton should have been synchronized marked, as they are open to multithreaded interaction. spring singletones are regular single point.

I think it’s wrong to say, if you have no condition at all, then everything is thread-safe. If you think the level is low, the methods also contain states, that is, local variables, and if several threads access them, you can also get a headache.

0
source

As already stated, your class is not thread safe. Prototype-scope is one way, but if a prototype bean is auto-detected in a singleton bean, it will still mean that only one instance of the prototype bean is created, which also makes it a singleton.

Synchronization is another way, but it only applies if the instance variables are intended to be shared between threads. If, however, the intention is that the instance variables should be unique for each thread, you should look at ThreadLocal .

0
source

Source: https://habr.com/ru/post/908960/


All Articles