Real life use cases for Singleton pattern;
If you are developing a client-server application, you need single instrance of ConnectionManager
, which manages the life cycle of client connections.
The basic APIs in ConnectionManager :
registerConnection
: Add new connection to existing list of connections
closeConnection
: Close the connection either from event triggered by Client or Server
broadcastMessage
: Some times, you have to send a message to all subscribed client connections.
I am not providing complete implementation of source code since example will become very lengthy. At high level, the code will be like this.
import java.util.*;
import java.net.*;
/* Lazy Singleton - Thread Safe Singleton without synchronization and volatile constructs */
final class LazyConnectionManager {
private Map<String,Connection> connections = new HashMap<String,Connection>();
private LazyConnectionManager() {}
public static LazyConnectionManager getInstance() {
return LazyHolder.INSTANCE;
}
private static class LazyHolder {
private static final LazyConnectionManager INSTANCE = new LazyConnectionManager();
}
/* Make sure that De-Serailzation does not create a new instance */
private Object readResolve() {
return LazyHolder.INSTANCE;
}
public void registerConnection(Connection connection){
/* Add new connection to list of existing connection */
connections.put(connection.getConnectionId(),connection);
}
public void closeConnection(String connectionId){
/* Close connection and remove from map */
Connection connection = connections.get(connectionId);
if ( connection != null) {
connection.close();
connections.remove(connectionId);
}
}
public void broadcastMessage(String message){
for (Map.Entry<String, Connection> entry : connections.entrySet()){
entry.getValue().sendMessage(message);
}
}
}
Sample Server class:
class Server implements Runnable{
ServerSocket socket;
int id;
public Server(){
new Thread(this).start();
}
public void run(){
try{
ServerSocket socket = new ServerSocket(4567);
while(true){
Socket clientSocket = socket.accept();
++id;
Connection connection = new Connection(""+ id,clientSocket);
LazyConnectionManager.getInstance().registerConnection(connection);
LazyConnectionManager.getInstance().broadcastMessage("Message pushed by server:");
}
}catch(Exception err){
err.printStackTrace();
}
}
}
Other practical use cases for Singletons:
ThreadPool, ObjectPool, DatabaseConnectionPool
etc.Logging
application data with different log levels like DEBUG,INFO,WARN,ERROR
etcRegistryService
where different services are registered with a central component on startup.That global service can act as a Facade
for the application