Since I found no question covering this topic, I thought I’d share my solution to the following scenario. The answer may be obvious, but I took the long route to find out. 🙂 I’d appreciate feedback to both the question and answer as well as other solutions.
Scenario:
Suppose you have a multi-threaded program and want a database connection (or some other shared object) for some functionality in your program while other parts of your program don’t need it at all. There should only ever be one connection to the db though.
At the same time, you want to detect db connection loss and try to reconnect on the fly.
To cover that, you implement a lazy load pattern “getter” that also checks connection validity before returning the connection object.
Your code may look like this:
public class Main {
private DB _db;
public static void main(String[] args) {
new Main().start();
}
private void start() {
// Program code goes here
// You create several threads, some of which may call getDB() whenever they need DB access
}
public DB getDB() {
if (_db == null) {
_db = getDBConnection();
} else if (!_db.isConnectionValid()) {
/*
* DB connection is not valid anymore. Let's close it and
* try to get a new connection.
*/
_db.close();
_db = getDBConnection();
}
return _db;
}
private DB getDBConnection() {
DB db;
// Obtain a new connection...
...
return db;
}
}
The problem:
Several threads may try to obtain a db connection at nearly the same time. It is even possible that several connects co-exist when some classes keep references to them.
In that case you need a pool as you can obtain multiple different instances. There are many DatabaseConnection pools available and some JDBC drivers have their own. I suggest you use the one which comes with the JDBC driver or use C3P0 or the like to act as Database connection pool.
More specifically you need to take a connection (not just get it) in a way that another thread cannot get the same connection. A trivial example is to use a Queue.