Stack overflow created by a cycle in code with singletons - java

I have two singleton classes, lets call them class A and class B.
The classes look like such.
class A
{
private static A instance;
private A(int timeout)
{
init();
}
public static A getInstance(int timeout)
{
if(instance == null)
{
instance = new A(timeout);
}
return instance;
}
private void init()
{
new Monitor().sendMonitorStatus();
}
}
and for class B
class B
{
private static B instance;
private B(A a)
{
}
public static B getInstance(A a)
{
if(instance == null)
{
instance = new B(a);
}
return instance;
}
}
Then there is a class named Monitor as well that looks as such.
class Monitor
{
public void sendMonitorStatus()
{
B.getinstance(A.getinstance(10));
}
}
The problem as you can see, is that I get a stackoverflow since it keeps a cycle of a call to B then calling A which calls B which calls A..., is there anyway to solve this problem without a redesign or is the only way to solve this cycle causing this error to redesign how the classes work?

To create an instance of A, you need to call Monitor::sendMonitorStatus. To call Monitor::sendMonitorStatus, you need an instance of A. You have a dependency cycle.
You need to redesign this. Exactly how – it depends on what you want to achieve.

Related

Conflicting understanding on singleton implementations

From my understanding a Singleton is a single instance of a class that lasts throughout the span of an applications lifetime. However I've seen a few different implementations of the systems, but I'm always informed that they're wrong, flawed, etc. etc. I'm going to post the two that I see more commonly and I would like to hear opinions/fact based on which implementation is better and why. Implementations are compilable.
Implementation A:
public class Foo {
private static Foo singelton;
private Foo() {
System.out.println("Bar");
}
public static Foo getSingleton() {
if(singleton == null) singleton = new Foo();
return singleton;
}
public static void main(String[] args) {
Foo.getSingleton();
}
}
Implementation B:
public class Foo {
private static final Foo singelton = new Foo();
private Foo() {
if(singelton != null) {
throw new IllegalStateException("Singleton class was already constructed.");
}
System.out.println("Bar");
}
public static void main(String[] args) {
// NOT REQUIRED
}
}
You'll notice in Implementation B that the Singleton instance is final. Also, because of the static implementation the main(String[]) method never needs to construct an instance of this class.
Both Implementation A and B will yield the same results.
Opinions?
Hey you have shown two implementations, the second one is called early initialization and first one is called lazy initialization, as it is initializing the class on demand only.
However your first initialization will fail in multi-threaded environment.
You have to use double checked locking to secure your code.
E. g. :
public class EagerSingleton {
private static volatile EagerSingleton instance = null;
// private constructor
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
if (instance == null) {
synchronized (EagerSingleton.class) {
// Double check
if (instance == null) {
instance = new EagerSingleton();
}
}
}
return instance;
}
}
For morer details please check :
http://howtodoinjava.com/2012/10/22/singleton-design-pattern-in-java/

Avoid Object Creation in Java

How to stop other classes to create the object of the class using new operator in java. For Example, i have one class A. i don't want any other class to create its object using new operator.
One Approach is that i can throw IllegalArgumentException in the constructor of class A.
is there any other?
public class A{
public A(){
throw IllegalArguementException();
}
}
The approach what you followed is wrong.. you can't create object of your class as well with this approach.
So you must make your construction private and write static method to get the instance of the class.
class Test
{
private Test(){ }
public static Test getTestInstance(){
return new Test();
}
}
Hope it helps,
You can do it by making the constructor private.
class A
{
int i;
private A()
{
i=1;
}
public static A getInstance()
{
return new A();
}
}
class B
{
A a;
public B()
{
/* a=new A(); //This doesn't compile */
}
}
Implementing Singleton in Java 5 or above version using Enum is thread safe and implementation of Singleton through Enum ensures that your singleton will have only one instance even in a multithreaded environment.
public enum SingletonEnum {
INSTANCE;
public void doYourStuff(){
System.out.println("Singleton using Enum");
}
}
And this can be called from clients :
public static void main(String[] args) {
SingletonEnum.INSTANCE.doYourStuff();
}
You can make the class abstract (though in this case no instance of this class can be instantiated by any class, so perhaps it's not what you want), or make the constructor private.
private A() {}
Make the constructor private.

Clear Singleton instance in Java

I have a Singleton class to save the state of an application's module.
This class simply have a lot of 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 a precise moment of the application lifecycle, i have the need to CLEAR the module's state. What i do now is to reset ALL the variables in ModuleState by a clearAll() method like this:
public void clearAll(){
a=null;
b=null;
c=null;
..
..
}
My question is the following : there is a cleaner method to do this reset? Possibly clearing the singleton instance itself, without resetting every class variable?
The problem with this approach is that i may have the need to add a new class variable to the ModuleState. In this case i must remember to add a line in the clearAll() method to reset the new variable.
What about ...
public static volatile ModuleState instance = null;
public static void reset() {
instance = new ModuleState();
}
p.s.: as per discussion below: in a multithreaded environment it's very important to synchronize the access on the instance because the JVM is allowed to cache its value. You can use volatile as shown above. Thanks to all!
Cheers!
no, this approach is perfectly acceptable. you are of course synchronizing access to these state objects in some way, right? otherwise you risk someone seeing a half-cleared config object.
another thing you could do to future-proof yourself against any extra state added in the future is store all of your state in a HashMap, for example, instead of individual fields. this way, clear()ing the hashmap ensures that all state is wiped and adding any extra state in the future becomes safer
You need to maintain the same object instance, in order to comply with the Singleton pattern, so your approach makes sense: altering the members.
However, if you wanted to clean it up a little bit, why not just have an internal list, like:
ArrayList<Object> members = new ArrayList<Object>();
// If it actually is Object, there's 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 binds the key word to the member.
HashMap<String,Object> members = new HashMap<String,Object>();
// Again, same parameterization rules apply.
For an ArrayList or a HashMap, the clearAll method might look like this:
public class ModuleState()
{
public void clearAll()
{
members.clear();
}
}
This method won't need to change.
May be 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();
}
}
Make an inner class to hold the fields, then replace that instance when you want to reset. The write to the field would make the change to 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 checking initialization code was not threadsafe. I fixed that too.
Note that to make this work, you must make the reference to values volatile and synchronize all access to it, otherwise (due to the java memory model) other threads than the one that calls reset() may see the old reference.

members initializing using "this"

here is my problem
class A{
private B b = new B(this); // line 2
A(){}
}
This is just an ex. code and works fine. But i have a doubt about this is used to current reference (instance of A). Class initializing happens before to get a class instance. So how can we put this in line 2. i asked does instantiation happen before initializing?
You bring up an interesting point. Here is a contrived instructional example that demonstrates a run time problem that can happen when using your example.
class A {
private boolean isInitialized = false;
private final B b = new B(this);
public A() {
initialize();
}
private void initialize() {
isInitialized = true;
}
public boolean isInitialize() {
return isInitialized;
}
public B getB() {
return b;
}
}
class B {
private boolean isInitialized = false;
final private A a;
public B(final A a) {
this.a = a;
initialize();
System.out.println("inB: a.isInitialize()=" + a.isInitialize());
}
private void initialize() {
isInitialized = true;
}
public boolean isInitialize() {
return isInitialized;
}
}
public static void main(final String[] args) {
final A a = new A();
System.out.println("inMain: a.isInitialize()=" + a.isInitialize());
System.out.println("inMain:a.getB().isInitialize()=" + a.getB().isInitialize());
}
Output:
inB: a.isInitialize()=false
inMain: a.isInitialize()=true
inMain:a.getB().isInitialize()=true
Using the passed reference to class A within class B runs the real risk of using an object that is not fully initialized.
Be careful.
This is not class initialization (try to debug new ClassA() step by step), it is actually instance initialization.
There can be some problems if the constructor (from ClassB) calls some functions from ClassA, which access some fields in ClassA that are not initialized.
Edit: this is done before the constructor is called.
this is used correctly. The constructor doesn't need to be called at all.
No need for changes, everything is fine. this is a valid reference to A.
this will show its existence when you create an object of class A. Instance variable are assigned after object creation and static variable are initialize as soon as class loads and also before creations of any object.
you cannot use above initialization in static block
static {
private B b = new B(this); // compiler error. you cannot use 'this' in static context.
}

How to avoid the creation of object in Java?

I am new to java programming,I have one class,for this class i created two object(obj1,obj2).i don't want to create other than these object,if any body wants to create one more object for this class that should refer to first,or second objects only(instead of creating one more object).how to do this?please refer below code
class B
{
void mymethod()
{
System.out.println("B class method");
}
}
class Myclass extends B
{
public static void main(String s[])
{
B obj1=new B();//this is obj1
B obj2=new B();//this is obj1
B obj3=new B();//don't allow to create this and refer this to obj1 or obj2
}
}
Thanks
azam
Check out the Singleton design pattern.
What you need is the Singleton design pattern.
Class B should look something like so:
class B
{
private static B instance = null;
private B()
{
//Do any other initialization here
}
public static B getInstance()
{
if (instance == null)
{
instance = new B();
}
return instance;
}
}
Then, in your Myclass, just do this:
B obj1 = B.getInstance();
B obj2 = B.getInstance();
Note: This is not thread safe. If you are looking for a thread safe solution please consult the Wiki Page.
EDIT: You could also have a static initializer
class B
{
private static B instance = null;
static
{
instance = new B();
}
private B()
{
//Do any other initialization here
}
public static B getInstance()
{
return instance;
}
}
Yeah singleton it seems the correct way consider the info your providing here.
The default singleton implementation would be the following:
public class Singleton {
//holds single instance reference
private static Singleton instance = null;
//private constructor to avoid clients to call new on it
private Singleton()
{}
public static Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return instance;
}
}
Now you can get the single instance of the object by calling :
Singleton instance = Singleton.getInstance();
Keep in mind though that if your working on a threaded enviroment, singleton by default is not thread-safe.
You should make the getInstance method synchronized to avoid unexpected returns.
public synchronized static Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return instance;
}
Cheers
Generally speaking you need a singleton pattern. You need to make the constructor to become a private method. Then you create a method to instantiate class B, hence class B can only be instantiated by this method. Have a look at the singleton pattern. It is what you want I believe.
create singleton Class, like
public Class A {
private static Class a = new A();
public A getA() {
return a;
}
}
Object of class A has already created in class A itself. You don't need to create it outside. Just use getA() method to retieve the class A's object.
Like :
A objA = A.getA();
This is called Singlton Pattern.
You can use a Singleton. You have 2 possiblilities for that.
1 . Lazy Creation (Here you make the instance when call the function getInstance() and you check if the instance already exists):
class B {
static private B instance;
private void mymethod() {
System.out.println("B class method");
}
static public B getInstance() {
if (instance == null) {
instance = new B();
}
return instance;
}
}
class Myclass extends B {
public static void main(String s[]) {
B obj1 = B.getInstance(); // this is obj1
B obj2 = B.getInstance();
}
}
2 . Eager creation (Here you make the instance when the Class is called for the first time):
class B {
static private B instance = new B();
private void mymethod() {
System.out.println("B class method");
}
static public B getInstance() {
return instance;
}
}
class Myclass extends B {
public static void main(String s[]) {
B obj1 = B.getInstance(); // this is obj1
B obj2 = B.getInstance();
}
}
be aware, that using a singleton is a big restriction to your code. It can be very annoying when it's not possible to instance more than one object.
Especially when you dont have acces to the source....
The Effective way in multi threaded application, the below logic will may help
public class Singleton {
private static volatile Singleton _instance;
private Singleton(){}
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
I suppose people have not understood the problem statement. It says, not more than 2 objects shall be created. Singleton creates a single object and blocks any further instantiation.
maintain a static variable in ur object class, incrementing by 1 to the upper limit of objects while creating object
when object > bounds needs to be created, select a random number in range[1,bound] and return that object.

Categories