JVM class loading mechanism using a single-mode embodiment

Hungry Chinese-style:
the so-called starving type, that is, when the program starts or singleton class is loaded, the singleton instance has been created. You may not use this object, which resulted in waste.

package com.zhb.classloader;

public class HungrySingleton {
    private HungrySingleton() {

    }
    private static HungrySingleton instance;

    static {
        instance = new HungrySingleton();
    }

    public static HungrySingleton getInstance() {
        return instance;
    }
}

Verify starving type:

package com.zhb.classloader;

public class HungrySingleton {
    public int count=0;
    private HungrySingleton() {
        System.out.println(Thread.currentThread().getName()+"\t 我是构造方法HungrySingleton()");
    }
    private static HungrySingleton instance;

    static {
        instance = new HungrySingleton();
    }

    public static HungrySingleton getInstance() {
        return instance;
    }

    public static void main(String[] args) throws InterruptedException {
//        for (int i = 0; i < 20; i++) {
//            Thread thread = new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    HungrySingleton.getInstance();
//                }
//            });
//            thread.start();
//        }
        System.out.println("123");
    }
}

Output:


5679451-64fc0c1a059cbb5a.png

We can see, we did not go to show the call getInstance in the main function, but it generates a singleton object.

Why can achieve a singleton pattern here?

Because static method call to initialize class will lead the class, it will lead to initialize static variables and work on the implementation of the static code block. In the life cycle of the class, the initialization only once. It is possible to ensure that only new object. In the embodiment, although not execute the getInstance (), but there is such a rule:
when the virtual machine executes a main method will first initialize the main class where the main. Therefore initializes singleton class.

Improved:
hungry man, single cases of class does not implement lazy loading, regardless of the future use do not always occupy the memory;
using the Initialization Demand Holder (IoDH) technology to solve the problem of a hungry man.

package com.zhb.classloader;

public class IODHsingleton {

    private IODHsingleton() {
        System.out.println("初始化");
    }

    //静态内部类
    private static class SingletonClass {
        //私有静态常量实例
        private static final IODHsingleton instance = new IODHsingleton();
    }

    public static IODHsingleton getInstance() {
        //调用内部类的静态字段,此时内部类初始化
        return SingletonClass.instance;
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 20; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    IODHsingleton.getInstance();
                }
            });
            thread.start();
        }
        //System.out.println("123");
    }
}

Only in this way just to call getInstance, only to trigger SingletonClass initialization, resulting in singleton object.
Output:


5679451-fbec1e60f2b5c606.png

20 threads simultaneously to call getInstance, would only print out an initialization, proved to be a singleton object.

Reproduced in: https: //www.jianshu.com/p/73f8e59e15f4

Guess you like

Origin blog.csdn.net/weixin_34080903/article/details/91186464