How to make thread safe singleton class which can accepts parameter? - java

I am trying to make a class as ThreadSafe Singleton but somehow I am not able to understand how to make ThreadSafe Singleton class which can accepts parameter.
Below is the class which I am using from this github link which I am using currently to make a connection to Zookeeper -
public class LeaderLatchExample {
private CuratorFramework client;
private String latchPath;
private String id;
private LeaderLatch leaderLatch;
public LeaderLatchExample(String connString, String latchPath, String id) {
client = CuratorFrameworkFactory.newClient(connString, new ExponentialBackoffRetry(1000, Integer.MAX_VALUE));
this.id = id;
this.latchPath = latchPath;
}
public void start() throws Exception {
client.start();
client.getZookeeperClient().blockUntilConnectedOrTimedOut();
leaderLatch = new LeaderLatch(client, latchPath, id);
leaderLatch.start();
}
public boolean isLeader() {
return leaderLatch.hasLeadership();
}
public Participant currentLeader() throws Exception {
return leaderLatch.getLeader();
}
public void close() throws IOException {
leaderLatch.close();
client.close();
}
public CuratorFramework getClient() {
return client;
}
public String getLatchPath() {
return latchPath;
}
public String getId() {
return id;
}
public LeaderLatch getLeaderLatch() {
return leaderLatch;
}
}
And this is the way I am calling the above class -
public static void main(String[] args) throws Exception {
String latchPath = "/latch";
String connStr = "10.12.136.235:2181";
LeaderLatchExample node1 = new LeaderLatchExample(connStr, latchPath, "node-1"); // this I will be doing only one time at just the initialization time
node1.start();
System.out.println("now node-1 think the leader is " + node1.currentLeader());
}
Now what I need is if I am calling these two below methods from any class in my program, I should be able to get an instance of it. So I am thinking to make above class as a Thread Safe Singleton so that I can access these two methods across all my java program.
isLeader()
getClient()
How do I make above class as ThreadSafe singleton and then make use of isLeader() and getClient() across all my classes to see who is the leader and get the client instance..
I need to do this only at the initialization time and once it is done, I should be able to use isLeader() and getClient() across all my classes.. Is this possible to do?
// this line I will be doing only one time at just the initialization time
LeaderLatchExample node1 = new LeaderLatchExample(connStr, latchPath, "node-1");
node1.start();
This is more of Java question not Zookeeper stuff..

A singleton which requires a parameter is a bit of a contradiction in terms. After all, you'd need to supply the parameter value on every call, and then consider what would happen if the value was different to an earlier one.
I would encourage you to avoid using the singleton pattern at all here. Instead, make your class a perfectly normal one - but use dependency injection to provide a reference to a single configured instance to all your classes that need it.
That way:
The singleton nature isn't enforced, it's just a natural part of you only needing one reference. If later on you needed two references (e.g. for different Zookeeper instances for some reason) you can just configure the dependency injection differently
The lack of global state generally makes things much easier to test. One test might use one configuration; another test might use a different one. No singleton, no problem. Just pass the relevant reference into the constructor of the class under test.

Related

Life cycle Simple Java Class/Object in EJB container

We all use simple Java classes without any annotation. When we use it in normal standalone application, we use 'New' keyword to create instance and use it.The object is created on heap.
If its not instantiated i can still access or use its static members.
My question is, if i deploy this simple class to EJB container, then what happens to it? I have not annotated it Stateless or Stateful or Entity, so how container manages it. Below is sample code. The POJO here (ClientCounter) does nothing special but is just for example:
#Stateless
public class WelcomeBean implements WelcomeBeanRemote {
private ClientCounter pojo = new ClientCounter();
#Override
public void showMessage() {
System.out.println("welcome client");
pojo.increment();
}
}
class ClientCounter {
private int count;
public void increment() {
count++;
}
}
And the client is:
public class Client {
public static void main(String []args) {
Properties jndiProps = new Properties();
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");
jndiProps.put(Context.PROVIDER_URL,"http-remoting://localhost:8080");
jndiProps.put("jboss.naming.client.ejb.context", true);
jndiProps.put(Context.SECURITY_PRINCIPAL, "admin");
jndiProps.put(Context.SECURITY_CREDENTIALS, "admin");
final String appName = "";
final String moduleName = "EJBProject02";
final String sessionBeanName = "WelcomeBean";
final String viewClassName = WelcomeBeanRemote.class.getName();
Context ctx = new InitialContext(jndiProps);
WelcomeBeanRemote bean =(WelcomeBeanRemote) ctx.lookup(appName+"/"+moduleName+"/"+sessionBeanName+"!"+viewClassName);
bean.showMessage();
System.exit(0);
}
}
Each time a #Stateless EJB3 is called, the container picks one from a previosly created pool (or creates a new one, if the pool is empty) and uses this instance to execute the called function. In your case, each one has a "new" ClientCounter, so its "counter" will always be 0 when instantiated and 1 just after the calling and before the container destroy it.
You can identify clearly this behavior adding the following to your EJB:
#PostConstruct
public void init() {
System.out.println(counter.getCount());
}
#PreDestroy
public void destroy() {
System.out.println(counter.getCount());
}
Obviously, you have to add a getCount() { return count; } on your ClientCounter.
If you really want to make this kind of counting, you have to pick another solution, because even if you try to make your count property static, you may face issues on concurrency and when using your EJB on a cluster.

Better design for initialization within constructor

I have a class that looks something like this which acts as factory for clients based on credentials retrieved from credentials service. It builds clients one time and returns that on every call.
public class ClientFactory {
private CredentialService credentialService;
private ClientA clientA;
public ClientFactory(CredentialService credentialService){
this.credentialService = credentialService;
//initialization in constructor
this.clientA = buildClientA(credentialService.getCredentials());
}
public ClientA getClientA(){
return clientA;
}
/** Build new ClientA using crendentials*/
private ClientA buildClientA(String credentials){
return new ClientA(credentials);
}
}
Issue that I see with this is line 2 in the constructor which basically start using dependency 'credentialService' to initialize other dependencies immediately. If some other developer moves around order of code in constructor, it will start failing. Other option is too change method getClientA() to this.
public ClientA getClientA(){
if(clientA == null) {
this.clientA = buildClientA(credentialService.getCredentials());
}
return clientA;
}
But it has thread safety issues. Is there a better way to design above class which avoids concerns I highlighted above?
Thanks
Well,
this.clientA = buildClientA(credentialService.getCredentials()); relies on the parameter credentialService passed to the constructor, not on the member this.credentialService. Therefore, the order of the initializations doesn't matter.
BTW, just to be safe and avoid confustion, I wouldn't use the same name for the parameter of the constructor and the member.
Just don't save off a reference to theCredentialService as an instance variable, and continue passing credentialService.getCredentials() to bulldClientA. You are already not using the instance variable credentialService.
What you call ClientFactory looks like it's really just a ClientA. So why not have a factory that depends on the credentials and share a reference to a ClientA if you want to avoid creating extra ClientA objects?
public class ClientFactory {
private final CredentialService credentialService;
public ClientFactory(CredentialService credentialService){
this.credentialService = credentialService;
}
public ClientA newClientA(String credentials){
return new ClientA(credentials);
}
}
If you want to have a pool of clients potentially, you can share a Supplier<ClientA> instead.
Supplier<ClientA> simpleSupplier = Suppliers.ofInstance(ClientFactory.newClientA()); // guava
Supplier<ClientA> allNewSupplier = () -> ClientFactory.newClientA(); // java 8 lambda
ClientA cachedClient = simpleSupplier.get();
ClientA newClient = allNewSupplier.get();

Java Static Factory conversion

On my Client/Server Desktop application. I have this problem of how I should properly code my JDBC class with my Models to ensure all persistence request can support concurrency. i.e., multiple models want to request update to its persistence counterpart simultaneously [without atmost delay].
The scenario goes like this. Following the classes located in the server application.
Persitence Package:
abstract class AbstractService {
// other fields
private final String tName, tId;
private final String sqlStatement;
public AbstractService(final String tName, final String tId) {
this.tName = tName;
this.tId = tId;
this.sqlStatement = ""; // SELECT statement
}
// java.sql.Connection() createConnection()
// methods
}
public class T1Service extends AbstractService {
private final String sqlDMLStatements;
public T1Service() {
super("t1", "t1Id");
this.sqlDMLStatements = ""; // other DML statements
}
// methods having return types of List<E>, Object, Boolean, etc.
// i.e., public List<E> listAll()
}
Communication class [Client class]
import java.net.*;
import java.io.*;
public class Client extends Observable{
private Socket socket;
private ObjectInputStream input;
private ObjectOutputStream output;
private Object message;
// Constructor
// Getters/Setters
// Other methods like open or close input/output
private class ReceiverRunnable implements Runnable
#Override
public void run() {
while(running) { // if socket is still open and I/O stream are open/initialized
try { message = input.readObject(); }
catch(Exception e) {}
finally { setChanged(); notifyObservers(); }
}
}
}
}
The Main Class [Server class]
import java.net.*;
public class Server {
private List<Client> clientList; // holds all active connections with the server
private T1Service t1Service
private class ConnectionRunnable implements Runnable {
#Override public void run() {
while(running) { // serverSocket is open
Client client = new Client(ServerSocket.accept(), /* other parameters */);
client.addObserver(new ClientObserver(client));
clientList.add(client);
}
}
}
private class ClientObserver implements Observer {
private Client client;
// Constructor
public void update(Observable o, Object arg) {
// Check the contents of 'message' to determine what to reply
// i.e., message.equals("Broadcast") {
// synchronized(clientList) {
// for(Client element : clientList) {
// element.getOutput().writeObject(replyObject);
// element.getOutput()..flush();
// }
// }
// i.e., message.equals("T1") {
// synchronized(t1Service) {
// client.getOutput().writeObject(t1.findAll());
// client.getOutput().flush();
// }
}
}
}
Since this is a Client/Server applcation, multiple request from the client are simultaneously feed to the server. The server process the request sending the appropriate reply to the approriate client. Note: All of the objects sent between Client & Server an instance of java.io.Serializable.
Having this kind of scenario and looking into the block of Server.ClientServer.update() we may have a performance issue or I should say a delay in processing the N client(s) request due to Intrinsic Locks. But since I have to the rules concurrency and synchronization to ensure that Server.T1Service won't get confused to the queue of N clients request to it. Here's are the questions:
According to the Item 1 of Effective Java - Second Edition regarding Static Factory, would this let me create a new class reference to the methods inside the classes of Persistence package?
Would each Client element inside List<Client> would form a concurrency issue having N client update their message field simultaneously triggering the ClientObsver.update() wherein the reference object(s) of this Observer is only a single instance in the parent class. I was avoiding creating multiple instance of T1Service due to memory concerns.
If we are going to go by the contents of Effective Java - Second Edition, how can I convert my persitence class in a way they can be read easily, easily instantiated, and support concurreny?
you may also want to review Actors, for example ones in Akka
basic idea of actors is avoiding of synchronization at all, using sending events. Akka will guarantee that one actor will never be invoked by two threads in parallel. So you may define actor, which does something with the global variables, and then simply send a message to it.
works like a charm usually :)
Is my theory of [Item 1] Static Factory correct?
Yes, you can use a static factory instead of constructors. Typically this is when you the construction logic is complex and shared between various subtypes to warrant a factory pattern. Additionally the factory may provide means for dependency injection outside of a DI framework.
Would it then solve the concurrency issue of the converted static factory global objects?
If you need to synchronize construction, then a static factory works well, just add synchronized to the method declaration on your factory methods. If you need to synchronize methods on the objects themselves then this will not help.
Is it advisable for me to convert to static factory if where dealing with concurrent access to a global object and where wanted real-time access to the methods of each global object?
As I answered above, it depends on what you are trying to achieve. For constructor synchronization use a factory.

Singleton Object in Java Web service

Good morning,
I am currently developing a java web application that exposes a web service interface. In order to keep a global object in memory, I use the following class as a Singleton:
public class SingletonMap {
private static final SingletonMap instance = new SingletonMap();
private static HashMap couponMap = null;
private static long creationTime;
private SingletonMap() {
creationTime = System.currentTimeMillis();
couponMap = new HashMap();
}
public static synchronized SingletonMap getInstance() {
return instance;
}
public static long getCreationTime() {
return creationTime;
}
}
I am using the above class in order to have the same instance of the HashMap for all the threads of the web service. The Web service class that maintains the SingletonMap object is the following:
#WebService()
public class ETL_WS {
private String TOMCAT_TEMP_DIR;
private final int BUFFER_SIZE = 10000000;
private static SingletonMap couponMap;
private static SingletonProductMap productCategoryMap;
private String dbTable = "user_preferences";
public ETL_WS() {
Context context = null;
try {
context = (Context) new InitialContext().lookup("java:comp/env");
this.TOMCAT_TEMP_DIR = (String) context.lookup("FILE_UPLOAD_TEMP_DIR");
}catch(NamingException e) {
System.err.println(e.getMessage());
}
public long getCouponMapCreationTime() {
return couponMap.getCreationTime();
}
}
The reason i have the method getCouponMapCreationTime() is to check that all the threads of the web service are accessing the same object. Is the above approach correct? How about performance overheads? Do you think I need the Singleton properties, or could I just use a static HashMap for all the threads? If I use a static HashMap, is it going to be garbage collected in case no thread is active?
Thank you for your time.
A JAX-WS web service is by itself a Singleton. This means that all the request will be handled using a single web service instance (like a Servlet).
So, any member of the class will be 'shared' between all the request. In your case, you do not need to make your members (i.e. couponMap) an static attributes.
Conclusion: Don't worry, all your threads (request) will be accessing the same 'couponMap'. Because you don't need the getCouponMapCreationTime anymore, I think that you can eliminate the SingletonMap abstraction and use directly a Map in your web service class.
But I have something very important to add. If several threads (request) will be accessing your Map you have to make it thread-safe!!! There are a lot of way to do this, but I will give an idea: Use a ConcurrentHashMap instead of a HashMap. This will make all your get(), put(), remove() operations thread-safe! If you need a larger scope you can use synchronized blocks, but please avoid synchronize methods because the scoop is too large and always synchronize over this object.
JAX-WS has its own patterns for creating singletons, you don't need to use static fields. You use the #Inject annotation into each service. See this blog post: http://weblogs.java.net/blog/jitu/archive/2010/02/19/jax-ws-cdi-java-ee-6-0 (but don't use #SessionScoped, use #Singleton)
Some other points:
HashMap isn't thread-safe, you need ConcurrentHashMap.
This catch(NamingException e) { System.err.println(e.getMessage()); is unhelpful. Rethrow it as a RuntimeException. You can't recover from it.
Don't worry about performance overhead at this stage. Measure it once you have something working.

Singleton with Arguments in Java Again

First, I have to admit my problem is similar to Singleton with Arguments in Java
I read it, but the solution doesn't work for me. I know the factory pattern is the best solution to that problem.
Here is my problem.
I create a "singleton" class to provide some common function, for example get a global configuration parameter. This class need a handler to access the system resources, for example read the configuration file. Cause this class just act as a lib, the handler must pass in from outside, and the Handler is a system class.
So, I write my code in this way:
public class SingletonGlobalParameters {
private static final SingletonGlobalParameters instance = new SingletonGlobalParameters ();
private boolean initial = false;
private String aParameter = null;
private SingletonGlobalParameters () { }
public static SingletonGlobalParameters getInstance() {
if (initial == false) {
throw exception...
}
return instance;
}
public void init(Handler h) {
if (initial == false) {
Handler fileHandler = h;
aParameter = fileHandler.read(); // something like this
initial = true;
}
}
public int getParameter() {
return aParameter;
}
}
I remove synchronization stuff to make question clear.
This implement looks ugly, right? The class must guarantee to initialize before use.
Any good ideas? Thanks very much, this problem has troubled me for some time.
OK! I give the real world problem. This is a Android problem.
public class Configuration {
private static final Configuration instance = new Configuration ();
private boolean initial = false;
private long timeStamp = -1;
private Configuration () { }
public static Configuration getInstance() {
if (initial == false) {
throw exception...
}
return instance;
}
public void load(Context context) {
if (initial == false) {
SharedPreferences loader = context.getSharedPreferences("Conf", Context.MODE_PRIVATE);
timeStamp = loader.getInt("TimeStamp", 0);
initial = true;
}
}
public int getTimeStamp() {
return timeStamp;
}
}
Is this make question clearer?
The right pattern is the one allowing you to do things you need. Do not be so dogmatic. Singleton with a parameter is widely used and acepted in android environment (parameter is usually context). But in plain java environment, dependency injection would be better as it
decouples code using you singleton from the fact it is singleton, and modalities of its creation. There are a plenty of DI frameworks,like picocontainer, spring, google guice - just pick your favorite
EDIT: When I wrote this answer, the question had no context - we didn't know it was an Android app. It may be that it's not a bad solution in this case; but I would at least think about other approaches. I'm leaving my answer below for the more general case.
I would attempt to move away from the singleton pattern to start with.
Why is each configuration parameter needed from many places? Could you encapsulate each aspect of configuration (possibly multiple parameters in a single aspect in some cases) and then use dependency injection (e.g. with Guice) to make those encapsulated versions available to the components that need them?
It's hard to give concrete advice when we really don't know what kind of app you're writing, but in general it's a good idea to move away from global state, and dependency injection often provides a clean way of doing this. It's not a panacea, and it could be that in some cases you can redesign in a different way, but it would be my first thought.

Categories