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();
}
Related
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.
In my WebSocket application I have Sets containing data that I share between sessions - each session can access all the data in the set. I do this by simply making the Sets static.
My understanding from reading around the web is that WebSockets (in my case running on Tomcat 8) follow the Single Thread Model, in that there is an individual thread for each session. So...
My question is; should I make the shared members synchronized, as they can be accessed by any WebSocket thread?
Or does WebSockets take care of this for me?
I'm assuming that I should synchronize everything shared, but just confirming! Thanks.
If you have multiple threads reading from a shared Set (or any non thread safe variable) that may be written(updated) at the same time then you need to synchronize them. Java 8 adds a new synchronizedSet method to Collections (see Collections.synchronizedSet). Prior to Java 8 you provide your own synchronization. More on creating a Java 8 synchronizedSet can be found in this documentation.
Even with Websockets the synchronization is needed because you have defined static data (a Set) that can be accessed by multiple websocket sessions simultaneously. Instance data (non-static variables) do not need synchronization because the single thread model guarantees that no two methods on your class (in the same session) can execute simultaneously. Information on the one thread per Websocket session can be found in this Oracle documentation. Specifically it says:
As opposed to servlets, WebSocket endpoints are instantiated multiple times. The container creates one instance of an endpoint for each connection to its deployment URI. Each instance is associated with one and only one connection. This behavior facilitates keeping user state for each connection and simplifies development because only one thread is executing the code of an endpoint instance at any given time.
So per instance variables (non-static) need no special synchronization. Websockets guarantees thread safety in the Single Thread Model. However this doesn't apply to shared data (static variables) between those instances. Because they can potentially operate in their own threads you need to provide synchronization where appropriate.
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.
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.
What is the best way in Java to create a singleton?
Should a DB connection be a singleton (being a singleton it's automatically thread-safe)? Because theoretical the DB can't be accessed by many users in the same time.
A DB connection should not normally be a Singleton.
Two reasons:
many DB drivers are not thread safe. Using a singleton means that if you have many threads, they will all share the same connection. The singleton pattern does not give you thread saftey. It merely allows many threads to easily share a "global" instance.
Personally, I think Singleton often leads to bad design: See this post (by somebody else) http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/
Instead of doing this consider a database pool. The pool is shared (and could be a singleton if you wanted). When you need to do database work your code does this:
getConnectioFromPool();
doWork()
closeConnection() // releases back to pool
Sample Pool Libraries:
http://commons.apache.org/dbcp/
http://jolbox.com/
The best way to create a singleton (as of today) is the enum singleton pattern (Java enum singleton)
I doubt, that a Singleton is necessary or of any value for a database connection. You probably want some lazy creation: a connection is created upon first demand and cached, further requests will be fullfilled with the cached instance:
public ConnectionProvider {
private Connection conn;
public static Connection getConnection() {
if (conn == null || conn.isClosed()) {
conn = magicallyCreateNewConnection();
}
return conn;
}
}
(not thread safe - synchronize, if needed)
What is the best way in Java to create
a singleton?
Follow the design pattern creation guidelines. i.e private constructor, etc.
Should a DB connection be a singleton
(being a singleton it's automatically
thread-safe)?
creating a DB connection as a singleton might be a poor design choice in many scenarios. Use it only if you are sure that you don't need DB concurrency. If you have multiple users logged in at the same time, or even if your single user spawns many threads that need to access the DB, then a DB Connection pool is a better choice. You can use either apache or tomcat db connection pools. THese classes are defined for example in the package
org.apache.commons.dbcp.*;
org.apache.tomcat.dbcp.dbcp.*;
where dbcp stands for database connection pooling.
The biggest reason for using a connection pool is that on average the time it takes for the DB access (DML etc) is much smaller than the time it takes to create a connection and then close the connection. Additionally, don't forget to close your ResultSet, PreparedStatement and Connection variables after the transaction is done.
Because theoretical the DB can't be
accessed by many users in the same
time.
Why not? DB in most cases is meant to be used concurrently. You have these DB isolation levels - READ_COMMITTED, READ_UNCOMMITTED, SERIALIZED etc.
SERIALIZED is the case where your DB becomes single user access.
Singletons are a pattern - there's no explicit way to create one, you just follow the design practice.
So, if you're using a database that can handle concurrent reads/writes (i.e. MySQL), you don't need to worry so much about thread safety. If you're using a DB that's doesn't do concurrent writes well (SQLite), then a singleton should theoretically work.