Different type of singleton pattern

I am studying a basic software development pattern.

The basic implementation of singleton classes is written as follows:

    public class MyObject{

       private volatile static MyObject obj;

       private MyObject(){/*Do some heavy stuff here*/}

       public static synchronized MyObject getInstance(){
         if(obj==null)
            obj=new MyObject();
         return obj;
       }    
    }

But since I have the wrong call, synchronous methods can be tough.

While I am returning the book, I presented this implementation of the Singleton class:

public class MyObjectHolder {

private volatile static Supplier<MyObject> myObjectSupplier = () -> createMyObj();
//myObjectSupplier is changed on the first 'get()' call

public static MyObject getMyObject(){
    return myObjectSupplier.get();
}

private static synchronized MyObject createMyObj(){
    class MyObjectFactory implements Supplier<MyObject> {
        private final MyObject clockTimer = new MyObject();
        public MyObject get() { return clockTimer; }
    }


    if(!MyObjectFactory.class.isInstance(myObjectSupplier)) {
        myObjectSupplier = new MyObjectFactory();
    }
    return myObjectSupplier.get();
}

public static class MyObject{

    private MyObject(){
        /*Do some heavy stuff here*/
    }

    public void someMethod(){
        /* ... */
    }
}

}


...   


    {
        /*In main MyObject instantiation*/
        MyObjectHolder.MyObject obj = MyObjectHolder.getMyObject();

    }

Now that the first call to 'createMyObj ()' has been completed, there is no heavy burden of invoking a method synchronously, but not if not checked.

Do you think that something is wrong with this type of implementation?

ps. MyObject should not be the inner class of MyObjectHold, but I thought it looked good.

+4
source share
3 answers

[] ,

public class SingletonObject {

    private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger();
    private static final AtomicInteger INVOKE_COUNT = new AtomicInteger();

    private static final class LazyHolder {

        private static final SingletonObject INSTANCE = new SingletonObject();

    }

    private SingletonObject() {
        System.out.println("new SingletonObject");
        INSTANCE_COUNT.getAndIncrement();
    }

    public static SingletonObject getInstance() {
        INVOKE_COUNT.getAndIncrement();
        return LazyHolder.INSTANCE;
    }

    public static int getInstanceCount() {
        return INSTANCE_COUNT.get();
    }

    public static int getInvokeCount() {
        return INVOKE_COUNT.get();
    }

}

, :

public static void main(String[] args) throws Exception {
    int n = 1000;
    List<Callable<SingletonObject>> invokers = new ArrayList<>();
    for (int i = 0; i < n; i++) {
        invokers.add(SingletonObject::getInstance);
    }
    ExecutorService es = Executors.newFixedThreadPool(n);
    es.invokeAll(invokers);
    es.shutdown();
    System.out.println("Number of Instances = " + SingletonObject.getInstanceCount());
    System.out.println("Number of Invokes = " + SingletonObject.getInvokeCount());
}

:

new SingletonObject
Number of Instances = 1
Number of Invokes = 1000

EDIT ( @Holger ):

SingletonObject.

public class SingletonObject {

    private static final SingletonObject INSTANCE = new SingletonObject();

    private SingletonObject() {
        System.out.println("new SingletonObject");
    }

    public static SingletonObject getInstance() {
        return INSTANCE;
    }

    public static void anotherStaticMethod() {
        System.out.println("I don't need the SingletonObject Instance...");
    }

}

, , - anotherStaticMethod()?

new SingletonObject
I don't need the SingletonObject Instance...

:

WIKIPEDIA :

Java Virtual Machine (JVM), Java (). SingletonObject JVM, . , . LazyHolder , JVM , LazyHolder. LazyHolder , getInstance SingletonObject, , JVM LazyHolder. LazyHolder INSTANCE (private) SingletonObject. JLS, , , getInstance . INSTANCE , getInstance INSTANCE - . - "" , ; , , . , (, ).

.

+4

Singleton java - enum :

public enum MyObject{

   Obj;

   MyObject(){/*Do some heavy stuff here*/}

}

Obj .

+3

Singleton pattern breaks (SRP) - :

  • .

Your second approach is trying to delegate this "forced singleton" to a separate class - after SRP. If you use a dependency injection infrastructure such as spring, you can achieve the same effect by specifying only the MyObject class and declaring this class a singleton in the spring context.

+2
source

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


All Articles