22

I am developing a design pattern, and I want to make sure that here is just one instance of a class in Java Virtual Machine, to funnel all requests for some resource through a single point, but I don't know if it is possible.

I can only think of a way to count instances of a class and destroy all instance after first is created.

Is this a right approach? If not, is there any other way?

Joe
  • 1,488
  • 3
  • 16
  • 27
  • 4
    Your question is confusing, but you can enforce `Singleton Pattern` to make sure only one instance is created. – Sufiyan Ghori Jan 05 '15 at 15:37
  • 10
    @sufiyan, if there are several classloaders in the JVM and each of them loads the Singleton, there would be more than one instance :) – Konstantin Yovkov Jan 05 '15 at 15:38
  • 1
    There's an argument that says you should reconsider this design. Google has implemented a Singleton Detector to make sure people don't use them in applications: https://code.google.com/p/google-singleton-detector/. Clusters won't honor your wish, either. – duffymo Jan 05 '15 at 15:39
  • 5
    @Joe, you can create a Singleton, but if you want it to be **shared** among **all** the classloaders in the JVM, you can checkout this thread: http://stackoverflow.com/questions/15156840/singleton-class-with-several-different-classloaders – Konstantin Yovkov Jan 05 '15 at 15:41
  • 1
    @kocko technically those are separate classes, so it's still one instance per class. – user253751 Jan 06 '15 at 01:17
  • Why would you want to do this? Why not make all the methods static instead? If you want shared global state, you can still have it with static non-final fields. – raptortech97 Jan 06 '15 at 05:27
  • @raptortech97 often it's done to make it easier to make it a non-singleton in the future, or so that the singleton can extend another class/implement an interface. – user253751 Jan 06 '15 at 07:07
  • possible duplicate of [What is an efficient way to implement a singleton pattern in Java?](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java) – nhahtdh Jan 06 '15 at 07:15

9 Answers9

36

Use the singleton pattern. The easiest implementation consists of a private constructor and a field to hold its result, and a static accessor method with a name like getInstance().

The private field can be assigned from within a static initializer block or, more simply, using an initializer. The getInstance() method (which must be public) then simply returns this instance,

public class Singleton {
    private static Singleton instance;

    /**
     * A private Constructor prevents any other class from
     * instantiating.
     */
    private Singleton() {
        // nothing to do this time
    }

    /**
     * The Static initializer constructs the instance at class
     * loading time; this is to simulate a more involved
     * construction process (it it were really simple, you'd just
     * use an initializer)
     */
    static {
        instance = new Singleton();
    }

    /** Static 'instance' method */
    public static Singleton getInstance() {
        return instance;
    }

    // other methods protected by singleton-ness would be here...
    /** A simple demo method */
    public String demoMethod() {
        return "demo";
    }
}

Note that the method of using “lazy evaluation” in the getInstance() method (which is advocated in Design Patterns), is not necessary in Java because Java already uses “lazy loading.” Your singleton class will probably not get loaded unless its getInstance() is called, so there is no point in trying to defer the singleton construction until it’s needed by having getInstance() test the singleton variable for null and creating the singleton there.

Using this class is equally simple: simply get and retain the reference, and invoke methods on it:

public class SingletonDemo {
    public static void main(String[] args) {
        Singleton tmp = Singleton.getInstance();
        tmp.demoMethod();
    }
}

Some commentators believe that a singleton should also provide a public final clone() method that just throws an exception, to avoid subclasses that “cheat” and clone() the singleton. However, it is clear that a class with only a private constructor cannot be subclassed, so this paranoia does not appear to be necessary.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Sufiyan Ghori
  • 18,164
  • 14
  • 82
  • 110
  • Instead of throwing an exception while cloning, you could `return this`? – Willem Van Onsem Jan 05 '15 at 15:58
  • 4
    @CommuSoft - That could lead to unexpected behavior by the consumer. If you call `clone`, you'd expect that a different reference would be returned. Better to be explicit and throw an exception. – Oren Hizkiya Jan 05 '15 at 17:08
  • 2
    To be fair this can be circumvented by having more than one classloader, but I guess the question was just asked in an awkward way and wasn't actually intentionally trying to get a solution that avoids that problem. – Voo Jan 05 '15 at 17:47
  • 10
    Actually, the easiest implementation of a singleton, since Java 1.4, is an enum with one value, and it does a better job of being a singleton than this does, since if you serialize and deserialize it, you just get the original instance back. (There's a way to add that to your implementation, with enough effort.) Josh Bloch in the updated edition of Effective Java recommends using enums in this way. – David Conrad Jan 05 '15 at 18:49
  • What's the advantage of using singletons over `static` methods in a class with a `private` constructor? – Cole Tobin Jan 06 '15 at 06:09
7

That's the well known Singleton pattern: you can implement this as follows:

public class SingletonClass {

    //this field contains the single instance every initialized.
    private static final instance = new SingletonClass();

    //constructor *must* be private, otherwise other classes can make an instance as well
    private SingletonClass () {
        //initialize
    }

    //this is the method to obtain the single instance
    public static SingletonClass getInstance () {
        return instance;
    }

}

You then call for the instance (like you would constructing a non-singleton) with:

SingletonClass.getInstance();

But in literature, a Singleton is in general considered to be a bad design idea. Of course this always somewhat depends on the situation, but most programmers advice against it. Only saying it, don't shoot on the messenger...

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
6

There is a school of thought that considers the Singleton pattern to in fact be an anti-pattern.

Considering a class A that you only wish to have one of, then an alternative is to have a builder or factory class that itself limits the creation of the number of objects of Class A, and that could be by a simple counter. The advantage is that Class A no longer needs to worry about that, it concentrates on its real purpose. Every class that uses it no longer has to worry about it being a singleton either (no more getInstance() calls).

Jool
  • 1,706
  • 16
  • 14
5

You want the Singleton pattern. There is an excellent discussion of how to implement this properly. If you do this right, there will only ever be one instance of the class.

Essentially what you are going to do is create a class, hold a single instantiated object of that class at the static level, and provide a static accessor to get it (getInstance() or similar). Make the constructor final so people can't create their own instances out of the blue. That link above has plenty of great advice on how to do this.

Community
  • 1
  • 1
Todd
  • 30,472
  • 11
  • 81
  • 89
4

Use enum. In Java enum is the only true way to create a singleton. Private constructors can be still called through reflection.

See this StackOverflow question for more details: Implementing Singleton with an Enum (in Java)

Discussion: http://javarevisited.blogspot.com/2012/07/why-enum-singleton-are-better-in-java.html

Community
  • 1
  • 1
Vlad Lifliand
  • 470
  • 2
  • 5
3

I can only think of a way to count instances of a class and destroy all instance after first is created. Is this a right approach ? If not, is there any other way ?

The correct technical approach is to declare all of the constructors for the class as private so that instances of the class can only be created by the class itself. Then you code the class only ever create one instance.

Other Answers show some of the ways to implement this, according to the "Singleton" design pattern. However, implementing a singleton like this has some drawbacks, including making it significantly harder to write unit tests.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
2

I prefer lazy singleton class, which overrides readResolve method.

For Serializable and Externalizable classes, the readResolve method allows a class to replace/resolve the object read from the stream before it is returned to the caller. By implementing the readResolve method, a class can directly control the types and instances of its own instances being deserialized.

Lazy singleton using /Initialization-on-demand_holder_idiom:

public final class  LazySingleton {
    private LazySingleton() {}
    public static LazySingleton getInstance() {
        return LazyHolder.INSTANCE;
    }
    private static class LazyHolder {
        private static final LazySingleton INSTANCE = new LazySingleton();
    }
    private Object readResolve()  {
        return LazyHolder.INSTANCE;
    }
}

Key notes:

  1. final keyword prohibits extension of this class by sub-classing
  2. private constructor prohibits direct object creation with new operator in caller classes
  3. readResolve prohibits creation of multiple instances of class during object de-serialization
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
1

For that you need to use singleton pattern, I am just posting a demo code for that that may useful for your understanding.

E.g: If I want only one object for this Connect class:

public final class Connect {

    private Connect() {}

    private volatile static Connect connect = null;

    public static Connect getinstance() {
        if(connect == null) {
            synchronized (Connect.class) {
                connect = new Connect();
            }
        }
        return connect;
    }
}

Here the constructor is private, so no one can use new keyword to make a new instance.

Chandan Rajput
  • 441
  • 5
  • 18
  • Why do you make this `volatile` and do you use `synchronized`? By simply using a field initializer, this is all handled correctly. – Willem Van Onsem Jan 05 '15 at 15:47
  • 3
    This is not thread safe - it is possible for two `Connect` objects to be created if two threads call `getInstance` at the same time when `connect == null`. – OldCurmudgeon Jan 05 '15 at 15:48
  • @OldCurmudgeon: indeed, the `if` should be placed in the `synchronized` (which creates a lot of overhead as well becaus each time the instance is queried, the semaphores are used). Although I don't see why one needs to make it that compilcated... – Willem Van Onsem Jan 05 '15 at 15:49
  • @CommuSoft - Just wait 'till you hit a threading issue, see how difficult it will be to track down the problem. It's not complicated if you ue an `enum` or a `static` initialiser. – OldCurmudgeon Jan 05 '15 at 15:53
  • Also, using `synchronized` on the `Class` is dangerous because another tool could also synchronize on your class a cause deadlock. – OldCurmudgeon Jan 05 '15 at 15:54
  • @OldCurmudgeon: well I don't vote against the use of *semaphores*, but by using a field with initialization, it's up to the compiler to make sure it is handled correctly. – Willem Van Onsem Jan 05 '15 at 15:55
  • @@OldCurmudgeon, can you tell me please, how is it leads deadlock ? – Chandan Rajput Jan 05 '15 at 15:58
  • @Rajput `new Thread() { public void run() { synchronized(Connect.class) { for(;;); } } }.start();` – Radiodef Jan 05 '15 at 17:42
  • If you want to create a singleton lazily, just put the static instance in a helper class. Then, it won't be created until you first reference it. See: http://stackoverflow.com/a/2008934/636009 – David Conrad Jan 05 '15 at 19:00
0
class A{
    private A(){

    }
    public static A creator(A obj){
        A ob=new A();
        return ob;
    }
    void test(){
        System.out.println("The method is called");
    }
}

class Demo{
    public static void main(String[] args){
        A ob=null;
        ob=A.creator(ob);
        ob.test();
    }
}
PEHLAJ
  • 9,980
  • 9
  • 41
  • 53
  • While your code may provide a solution to the OP's issue, please ensure you explain your code clearly. Code-only answers may be confusing for the OP or future users. – Geoff James May 21 '17 at 16:16
  • This solution does not meet the requirement, *that there is just one instance of class* `A`. Instead, a new instance of `A` is created and returned each time, when the user calls method `A.creator`. – Thomas Fritsch May 21 '17 at 16:19