单例模式

单例模式(Singleton)是设计模式中最简单的一个,他的设计原则是保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

一下是五种单列设计写法

方法一

public class Main {
    private static final Main INSTANCE = new Main();

    private Main() {};

    public static Main getInstance() {
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }
}

构造方法只构造一次,可以使用private方法限制掉。类加载内存后,就实例话一个单列,JVM保证线程安全。

缺点:不管用到与否,类加载时就完成实例。

方法二

public class Main {
    private static final Main INSTANCE;
    static {
        INSTANCE = new Main();
    }

    private Main() {};

    public static Main getInstance() {
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }
}

与第一种类似

方法三

public class Main {
    private static Main INSTANCE;

    private Main() {
    }

    public static synchronized Main getInstance() {
        if (INSTANCE == null) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Main();
        }
        return INSTANCE;
    }
}

此方法类在需要的时候加载,虽然达到了按需初始化的目的,但却带来线程不安全的问题
可以通过synchronized解决,但也带来效率下降

方法四

public class Main {
    // 添加valatile,防止重排
    private static volatile Main INSTANCE;

    private Main() {
    }

    public static Main getInstance() {
        if (INSTANCE == null) {
            //双重检查
            synchronized (Main.class) {
                if(INSTANCE == null) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    INSTANCE = new Main();
                }
            }
        }
        return INSTANCE;
    }
}

虽然问题得已解决,但也带来效率下降。

方法五

public class Main {

    private Main() {
    }

    private static class MainHolder {
        private final static Main INSTANCE = new Main();
    }

    public static Mgr07 getInstance() {
        return MainHolder.INSTANCE;
    }
}

静态内部类方式
JVM保证单例
加载外部类时不会加载内部类,这样可以实现懒加载
这种写法更好一些