Spring MVC Singleton thread safety? - java

I have a singleton Spring bean (default scope). So, one instance will be used by multiple threads. However, I'm a bit confused with regards thread safety, apparently all Spring beans are thread safe if they are stateless, but my bean is not stateless, it has various instance variables which 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();
}
So, the fields above will be accessed by multiple threads - is it enough to mark these fields as volatile, or do I have to mark the methods which access them (there are a lot in not only this class, but other controllers/classes as well) with synchronized and use wait/notify etc?
Many thanks!

Spring itself makes sure to properly publish your beans once they have been instantiated, injected, etc. This means that any thread having a reference to your singleton bean will at least see its state as it was at the end of the Spring context creation.
If the state is immutable, you don't have anything to do.
If the state of the singleton is mutable, you will have to properly synchronize the accesses to this mutable state, though.

volatile does not help. It would 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 thread-locally: all reads and writes will go straight to "main memory";
Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.
Making the method synchronized will only help if your control flow never exit the (outer) synchronized block between the first write and the last read to the shared variables, and all shared variables are only accessed within synchronized blocks that use the same lock object.
So the general solution is to prevent shared variables in this scenario. One easy way to make the class immutable is to use local variables and method parameters instead of shared instance variables.
You wrote "Spring beans are thread safe if they are stateless, but my bean is not stateless." -- Ok that theme is discussed in the paragraph above.
But in from your code is seams that this is not the problem! The variables marked with final so they are immutable. If the fields of that object behaves in the same way (are not updated or are adequate protected against concurrent modification problems) you do not have mutable shared variables. Sometimes this is called "effective stateless". This means the values are not changed. So this is no problem for concurrency, (because the concurrency problem is about changing values).
In the end: You can use this effective stateless class from the example in different threads without a synchronized block if the fields (PcrfRecord...) are effective stateless. (If the fields PcrfRecord... are not stateless then the class PcrfSimulator can not been called effective stateless) -- But this has noting to to with Spring, it is plain Java.
Btw: if your variable is final you do not need to make them volantile.

Your class won't be thread-safe, if you mark it as singleton in context since you initialize
the fields with "new" manually which happens once as the bean is created and of which you will have one instance in memory like your singleton and accordingly, your threads share the instance of CustomGxSessionIdCacheImpl, PcrfRecord and so on.
If you can make these instances take under control of spring context, like:
<bean id="customGxSessionIdCache" class="package.CustomGxSessionIdCacheImpl" scope="prototype">
and autowire them in PcrfSimulator like:
#Autowired
private final CustomGxSessionIdCacheImpl gxSessionIdCache
after that, as soon as your code access on gxSessionIdCache, spring creates a new instance for each access and for each thread respectively. Any other methods in Singleton had to be marked with synchronized since these are open for multi-thread acceess. Spring singletons are regular singletons.
I think, it is wrong to say, if you have no state at all, then everything is thread-safe. If you think low-level, the methods have also states, i.e. local variables, and if multiple threads access these, you can get also a headache.

As has been established already, your class is not thread-safe. Prototype-scope is one way to go, but if a prototype-scoped bean is autowired into a singleton bean, it will still mean that only one instance of the prototype bean is created, effectively making it singleton as well.
Synchronization is another way to go, but that really only applies if the instance variables are meant to be shared between threads. If, however, the intention is that the instance variables should be unique to each thread, you should look at ThreadLocal instead.

Related

How to consider singleton in production code?

I have some java classes in which the members variables are all Autowired using Spring beans. I think that guarantees the singleton pattern. But I wonder how does the code run on a production server? Is singleton guaranteed per thread or is it guaranteed globally? How should I think about concurrency in development.
EDIT
An example:
A class the takes requests and response the number of requests it has received.
In this case we need to guarantee the global singleton of the counter, right? Say no matter how many servers we use, there should only be one counter. Is this guarantee implicitly?
Scope of classic singletons and Spring singletons
Singleton generally means singleton for the whole application running on a JVM.
That is the case for Java classic implementations where you implement it yourself (singleton double check idiom, enum idiom, initialization-on-demand holder idiom, and so for).
In these cases, the singleton is indeed created on the classloading of the singleton class, so a single time by the JVM.
Spring singletons work a little differently.
They indeed depend on the container. So, if you create multiple containers in a same JVM, you may create multiple singletons. Now it is really a corner case and besides these singleton beans are isolated between. So don't focus on it.
About concurrency
Singletons don't have any concurrency issue while these are immutable.
Of course, you can define dependencies and properties in a singleton.
But these should not change after the singleton instantiation.
Indeed if a singleton provides methods that allow to change its state, you are bound to have race conditions for distinct threads that manipulate that.
So as a hint, keep your singletons immutable or as immutable as you can.
If these cannot be completely immutable, you have to ensure that the race conditions are handled by synchronizing the methods/fields that need to.

Should I mark object attributes as volatile if I init them in #PostConstruct in Spring Framework?

Suppose, that I do some initialization in Spring singleton bean #PostConstruct (simplified code):
#Service
class SomeService {
public Data someData; // not final, not volatile
public SomeService() { }
#PostConstruct
public void init() {
someData = new Data(....);
}
}
Should I worry about someData visibility to other beans and mark it volatile?
(suppose that I cannot initialize it in constructor)
And second scenario: what if I overwrite value in #PostConstruct (after for example explicit initialization or initialization in constructor), so write in #PostConstruct will not be first write to this attribute?
The Spring framework is not tied into the Java programming language, it is just a framework. Therefore, in general, you need to mark a non-final field that is accessed by different threads to be volatile. At the end of the day, a Spring bean is nothing more than a Java object and all language rules apply.
final fields receive a special treatment in the Java programming language. Alexander Shipilev, The Oracle performance guy, wrote a great article on this matter. In short, when a constructor initializes a final field, the assembly for setting the field value adds an additional memory barrier that assures that the field is seen correctly by any thread.
For a non-final field, no such memory barrier is created. Thus, in general, it is perfectly possible that the #PostConstruct-annotated method initializes the field and this value is not seen by another thread, or even worse, seen when the constructor is yet only partially executed.
Does this mean that you always need to mark non-final fields as volatile?
In short, yes. If a field can be accessed by different threads, you do. Don't make the same mistake that I did when only thinking of the matter for a few seconds (thanks to Jk1 for the correction) and think in terms of your Java code's execution sequence. You might think that your Spring application context is bootstraped in a single thread. This means that the bootstraping thread will not have issues with the non-volatile field. Thus, you might think that everything is in order as long as you do not expose the application context to another thread until it is fully initialized, i.e. the annotated method is called. Thinking like this, you could assume, the other threads do not have a chance to cache the wrong field value as long as you do not alter the field after this bootstrap.
In contrast, the compiled code is allowed to reorder instructions, i.e. even if the #PostConstruct-annotated method is called before the related bean is exposed to another thread in your Java code, this happens-before relationship is not necessarily retained at in the compiled code at runtime. Thus, another thread might always read and cache the non-volatile field while it is either not yet initialized at all or even partially initialized. This can introduce subtle bugs and the Spring documentation does unfortunately not mention this caveat. Such details of the JMM are a reason why I personally prefer final fields and constructor injection.
Update: According to this answer in another question, there are scenarios where not marking the field as volatile would still produce valid results. I investigated this a little further and the Spring framework guarantees as a matter of fact a certain amount of happens-before safety out of the box. Have a look at the JLS on happens-before relationships where it clearly states:
An unlock on a monitor happens-before every subsequent lock on that monitor.
The Spring framework makes use of this. All beans are stored in a single map and Spring acquires a specific monitor each time a bean is registered or retrieved from this map. As a result, the same monitor is unlocked after registering the fully initialized bean and it is locked before retrieving the same bean from another thread. This forces this other thread to respect the happens-before relationship that is reflected by the execution order of your Java code. Thus, if you bootstrap your bean once, all threads that access the fully initialized bean will see this state as long as they access the bean in a canonical manner (i.e. explicit retrieval by querying the application context or auto-wriring). This makes for example setter injection or the use of a #PostConstruct method safe even without declaring a field volatile. As a matter of fact, you should therefore avoid volatile fields as they introduce a run time overhead for each read what can get painful when accessing a field in loops and because the keyword signals a wrong intention. (By the way, by my knowledge, the Akka framework applies a similar strategy where Akka, other than Spring, drops some lines on the problem.)
This guarantee is however only given for the retrieval of the bean after its bootstrap. If you change the non-volatile field after its bootstrap or if you leak the bean reference during its initialization, this guarantee does not longer apply.
Check out this older blog entry which describes this feature in further detail. Apparently, this feature is not documented as even the Spring people are aware of (but did not do anything about in a long time).
Should I worry about someData write visibility to other beans and mark it volatile?
I see no reason why you should not. Spring framework provides no additional thread safety guarantees when calling #PostConstruct, so usual visibility issues may still happen. A common approach would be to declare someData final, but if you want to modify the field several times it obviously won't fit.
It should not really matter if it's the first write to the field, or not. According to Java Memory Model reordering/visibility issues apply in both cases. The only exception is made for final fields, which can be written safely on the first time, but later assignments (e.g. via reflection) are not guaranteed to be visible.
volatile, however, can guarantee necessary visibility from the other threads. It also prevents an unwanted exposure of partly-constructed Data object. Due to reordering issues someData reference may be assigned before all neccessary object creation operations are completed, including constructor operations and default value assignments.
Update: According to a comprehensive research made by #raphw Spring stores singleton beans in monitor-guarded map. This is actually true, as we can see from the source code of org.springframework.beans.factory.support.DefaultSingletonBeanRegistry:
public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
...
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
This may provide you with a thread-safety properties on #PostConstruct, but I would not consider it as sufficient guarantee for a number of reasons:
It affect only singleton-scoped beans, providing no guarantees for the beans of other scopes: request, session, global session, accidentally exposed prototype scope, custom user scopes (yes, you can create one by yourself).
It ensures write to someData is protected, but it gives no guarantees to the reader thread. One can construct an equivalent, but simplified example here, where data write is monitor-guarder and reader thread is not affected by any happens-before relationship here and can read outdated data:
public class Entity {
public Object data;
public synchronized void setData(Object data) {
this.data = data;
}
}
The last, but not least: this internal monitor we're talking about is an implementation detail. Being undocumented it is not guaranteed to stay forever and may be changed without further notice.
Side note: All stated above is true for beans, that are subject of multithreaded access. For prototype-scoped beans it is not really the case, unless they are exposed to several threads explicitly, e.g. by injection into a singleton-scoped bean.

What is a real use-case for #Stateless over #Singleton in EJB

if I understand EJB correctly, #Singleton is actually the same as Singleton in plain Java and also singleton in spring -> one instance, every call goes through the same instance concurrently.
#Stateless declares a bean, that could (but must not) have multiple instance, with the limitation that only one call can be in an instance at the same time. Right sofar?
This remains me on the servlet programming model: in theory servlet containers are allowed to make multiple copies of the servlet, in practice I haven't seen any servlet container to do so.
So assuming I do not have REALLY LIMITED resources like doors, windows or printers in my code (and if I did I could still solve it with queues and stuff), what is the REAL example, where usage of #Stateless is advantageous over usage of #Singleton.
regards
Leon
You can have multiple instances of a stateless bean to increase throughput.
On the other hand there is only one instance of a singleton. The reason for this is normally to share state in application scope, serializes access to resources etc., and this implies locking or synchronization.
So if you are not really having a singleton, then use a stateless bean.
If you have a "stateless singleton", there is no difference. But if you read "singleton", it has a special meaning by convention (= there must be a reason for using the singleton pattern).
Stateless implies that the bean is thread safe. This is because there is no code in the bean that relies on state. This means that running any of its methods will not affect future running of said methods.
An example of a stateless class would a class that does addition and subtraction. All the necessary parameters are passed into the method. Doing an addition or subtraction does not alter the way these methods work at a later call. This implies that you do not need to worry about concurrency with the class.
A singleton is usually used for a class that is very expensive to create such as a Database connection. You do not want every class creating a new Database connection every time they need to use the database so you have it instantiated once at program start up. Being a singleton does not necessarily mean that the class is thread safe (although it absolutely should be).
So Stateless means the class is threadsafe.
Singleton refers to the fact that the class is only created once. While this heavily implies that the class is (AND IT SHOULD BE) thread safe, it does not directly imply it like stateless does.

Advice on using ThreadLocals to wrap mutable singleton objects

From Java Concurrency in practice Chapter 3.3.3. ThreadLocal
Thread-local variables are often used to prevent sharing in designs
based on mutable Singletons or global variables.
If we wrap the mutable Singleton guy in a ThreadLocal each thread will have its own copy of the Singleton ? How will it remain a singleton then ? Is this what the authors meant or am I missing something pretty obvious here ?
If we wrap the mutable Singleton guy in a ThreadLocal
AFAIK you do not wrap the singleton class with ThreadLocal, but the object contained within the singleton which is mutable or non-thread safe. As the example discusses correctly that the JDBC Connection is not thread safe and will require additional protection, which in turn increases contention.
So in the cases when the Singletons are used just for the purpose of sharing, then replacing those things with ThreadLocal is a good idea, as all the threads have their own Connection and no more added protection is required.
Other good example of use case of ThreadLocal is Random generation, if there is a single Random object then there is contention within threads for the "seed", so if each thread has its own Random object then there is no contention any more and that makes sense.
If you wrap a Singleton (as a design pattern) in a ThreadLocal it will remain a Singleton. There is no big magic in a ThreadLocal, if you check the source of the ThreadLocal you just saw it. It uses a Map and uses the current thread as a key. So it is quite useless to put a Singleton (a well implemented one) in a ThreadLocal. As you only get the same Singleton in various ways.
I suppose the author means that if your design heavily using Singletons and/or global variables the ThreadLocal is a good choice if you need something unique per thread, and do not want to pass all the way down the call hierarchy. But this thing is different from a Singleton. Of course you can have a ThreadLocal encapsulated in your Singleton so it will have some thread specific state (but that I would not call a Singleton anymore)
what I understood with this line is that when an application has been design in a manner where a Singleton class has mutable state which is being read and written by many threads will require thread safety so you need to serialize all access to that state. You may consider creating a ThreadLocal on that mutable singleton. (from the book:-)
For example, a single‐threaded application might maintain a global database connection that is initialized at startup to avoid having to pass a Connection to every method. Since JDBC connections may not be thread‐safe, a multithreaded application that uses a global connection without additional coordination is not thread‐safe either. By using a ThreadLocal to store the JDBC connection, as in ConnectionHolder in Listing 3.10, each thread will have its own connection.
private static ThreadLocal<Connection> connectionHolder= new ThreadLocal<Connection>() {
public Connection initialValue() {
return DriverManager.getConnection(DB_URL);
}
};
public static Connection getConnection() {
return connectionHolder.get();
}

Why pool Stateless session beans?

Stateless beans in Java do not keep their state between two calls from the client. So in a nutshell we might consider them as objects with business methods. Each method takes parameters and return results. When the method is invoked some local variables are being created in execution stack. When the method returns the locals are removed from the stack and if some temporary objects were allocated they are garbage collected anyway.
From my perspective that doesn’t differ from calling method of the same single instance by separate threads. So why cannot a container use one instance of a bean instead of pooling a number of them?
Pooling does several things.
One, by having one bean per instance, you're guaranteed to be threads safe (Servlets, for example, are not thread safe).
Two, you reduce any potential startup time that a bean might have. While Session Beans are "stateless", they only need to be stateless with regards to the client. For example, in EJB, you can inject several server resources in to a Session Bean. That state is private to the bean, but there's no reason you can't keep it from invocation to invocation. So, by pooling beans you reduce these lookups to only happening when the bean is created.
Three, you can use bean pool as a means to throttle traffic. If you only have 10 Beans in a pool, you're only going to get at most 10 requests working simultaneously, the rest will be queued up.
Pooling enhances performance.
A single instance handling all requests/threads would lead to a lot of contention and blocking.
Since you don't know which instance will be used (and several threads could use a single instance concurrently), the beans must be threadsafe.
The container can manage pool size based on actual activity.
The transactionality of the Java EE model uses the thread context to manage the transaction lifecycle.
This simplification exists so that it is not necessary to implement any specific interface to interact with the UserTransaction object directly; when the transaction is retrieved from the InitialContext (or injected into the session bean) it is bound to a thread-local variable for reuse (for example if a method in your stateless session bean calls another stateless session bean that also uses an injected transaction.)
Life cycle of the Statelesss session beans are Doesnot exist, Passive and MethodReady(Passive or Inactive) state.To optimize on perormance, instead of traversing the bean all through from create to method ready state, container manages the bean between active and passive states through the container callbacks - ejbActivate() and ejbPassivate() there by managing the bean pool.
sreenut
Methods by nature ARE THREAD SAFE (including static). Why? Simple, because every variable inside the method is created in the stack memory, i.e. every variable used inside the method is created per call (it's not shared). However, parameters aren't part of the stack.
However, a method is unsafe if it uses an unsafe variable:
a) calling a static field or variable. However, it happens in every single case.
b) calling a resource that it's shared. Such as the EntityManager.
c) passing a parameter that is not safe.

Categories

Resources