Clear Singleton instance in Java

I have a Singleton class to save the state of an application module. This class simply has many class variables with setters and getters:

public class ModuleState{ private static ModuleState instance; private A a; private B b; private C c; .. .. .. .. private ModuleState (){} public ModuleState getInstance(){ if(instance==null) instance=new ModuleState(); return instance; } 

}

At the exact moment in the application life cycle, I have a need to clear the state of the module. What I'm doing now is reset ALL variables in ModuleState using the clearAll () method:

 public void clearAll(){ a=null; b=null; c=null; .. .. } 

My question is this: is there a cleaner way to reset this? Perhaps flushing the singleton instance itself without resetting each class variable?

The problem with this approach is that I may need to add a new class variable to ModuleState. In this case, I should remember adding a line to the clearAll () method to reset the new variable.

+4
source share
5 answers

What about...

 public static volatile ModuleState instance = null; public static void reset() { instance = new ModuleState(); } 

ps : as discussed below: in a multi-threaded environment, it is very important to synchronize access to an instance, since the JVM allowed its value cache . You can use volatile as shown above. Thanks everyone!

Hooray!

+8
source

no, this approach is quite acceptable. Do you, of course, synchronize access to these state objects, anyway? otherwise, you risk someone seeing a semi-cleaned configuration object.

one more thing you could do so that future protection against any additional state added in the future stores all your state in a HashMap, for example, instead of separate fields. Thus, clear () in hashmap ensures that the entire state is erased, and adding any additional state in the future will be safer

+2
source

You need to maintain the same instance of the object to fit the Singleton pattern, so your approach makes sense: changing members.

However, if you want to clear it a bit, why not just have an internal list, for example:

  ArrayList<Object> members = new ArrayList<Object>(); // If it actually is Object, there no need to paramaterize. // If you want, you can actually make the members implement a common interface, // and parameterize the ArrayList to that. 

Another option would be to have a HashMap that associates a keyword with an element.

  HashMap<String,Object> members = new HashMap<String,Object>(); // Again, same parameterization rules apply. 

For ArrayList or HashMap the clearAll method might look like this:

 public class ModuleState() { public void clearAll() { members.clear(); } } 

This method does not need to be changed.

+1
source

Make an inner class to hold the fields, and then replace this instance if you want to reset. A field entry would modify all three fields, essentially atomic.

 public class ModuleState { private static volatile ModuleState instance; private static class Values { A a; B b; C c; } private volatile Values values = new Values()( private ModuleState (){} public ModuleState getInstance(){ if (instance==null) { synchronized (ModuleState.class) { if (instance==null) { instance = new ModuleState(); } } } return instance; } public synchronized A getA() { return values.a; } public synchronized void reset() { values = new Values(); } 

By the way, your null check initialization code was not thread safe. I fixed it too.

Please note that to do this, you must make a link to values volatile and synchronize all access to it, otherwise (due to the java memory model) other threads, except the one that calls reset (), can see the old link .

0
source

Maybe this can help you:

 public class SingletonBean { private static SingletonBean instance = new SingletonBean(); private static Object privateMutex = new Object(); private SingletonBean() { //to prevent instantiation } public class ObjectsContainer { private Object A; private Object B; private Object C; public Object getA() { return A; } public void setA(Object a) { A = a; } public Object getB() { return B; } public void setB(Object b) { B = b; } public Object getC() { return C; } public void setC(Object c) { C = c; } } private ObjectsContainer objectsContainer; private void resetObjectsContainer() { objectsContainer = new ObjectsContainer(); } public static SingletonBean getInstance() { return SingletonBean.instance; } public static void clearAll() { synchronized (privateMutex) { SingletonBean.getInstance().resetObjectsContainer(); } } public static ObjectsContainer getObjectsContainer() { synchronized (privateMutex) { return instance.objectsContainer; } } } public class SomeClass { public void someMethod() { SingletonBean.getObjectsContainer().getA(); } } 
0
source

Source: https://habr.com/ru/post/1480320/


All Articles