单例模式

使用懒汉式加载。 最终能够作到 线程安全,延迟加载,效率高的特色。java

package oneDay;

/**
 * 保证一个类仅有一个实例,并提供一个访问它的全局访问点
 * 1:构造方法私有化
 * 2:声明一个本类对象
 * 3:给外部提供一个静态方法获取对象实例
 * <p>
 * <p>
 * 单例设计模式的存在是为了什么?
 * 1:在设计一些工具类的时候,不须要属性这些东西,只须要方法就能够,因此就不掺和对象,只用单例就能够.
 * 2:工具类可能会被频繁调用.
 * 目的是为了节省重复建立对象所带来的内存消耗.从而提升效率.
 * <p>
 * 能不能使用构造方法私有化再加上static 来替代单例?   不能, 构造方法 不能静态化.
 * <p>
 * <p>
 * 在类被加载的时候 由于类中的实例是有 static修饰的,因此当时的实例已经建立好了.
 * 而后继续getIntance的时候  获得的就是 同一个对象.
 */
public class singleCase {
    public static void main(String[] args) {

    }
}


// 饿汉式 : 在类被加载后,对象被建立,到程序结束以后释放.
class Singleton1 {
    private Singleton1() {
    }

    private static Singleton1 s = new Singleton1();

    public static Singleton1 getInstance() {
        return s;
    }

    public void print() {
        System.out.println("测试方法1!");
    }
}
// 懒汉式  : 在第一次调用getInstance方法时,对象被建立,到程序结束后释放.
// 在多线程访问的时候 可能会由于生命周期的问题  而出现程序崩溃错误.
// 可能出现 第一个线程进入 getInstance的时候, 发现s为空 , 在没有 声明实例的时候, 第二个进程也发现了 s 为空.  这个时候   实例就变了.
// 解决方法:
// 1: 将getInstance加上线程锁, 可是这样的话就是 串行执行了 . 效率的良心大大滴坏了.
// 2: 还有一种说话 是给 s = new Singleton2(); 加上同步代码块, 可是这样显然无法解决  实例变化的问题. 是个扯淡的方法.

class Singleton2 {
    private Singleton2() {
    }

    private static Singleton2 s;

    public static Singleton2 getInstance() {
        if (s == null)
            s = new Singleton2();
        return s;
    }

    public void print() {
        System.out.println("测试方法2!");
    }
}

// 3: 结合第二种方法, 实现第三种方法 . 加上同步代码块减小锁影响的颗粒大小, 而且避免第二种方法的问题.  就是在同步代码块中  再次判断是否为空.
//  双重加锁法.  可是这样还可能会存在问题.  由于牵扯到 JVM实现 s = new Singleton3(); 的指令顺序问题 .
//  其指令大体分为如下三步:   1 申请一块内存空间用于存放实例内容 2 在该空间实例化对象  3  将该内存地址富裕s
//  底层执行的时候  不必定是按照123 执行的,  有多是132 (底层代码速度优化方案.). 这样的话 在没有实例化对象的时候 , s不为null , 这样另外一个线程发现s 不为空, 可是拿到的是空的s , 这个时候程序就炸了.
class Singleton3 {
    private Singleton3() {
    }

    private static Singleton3 s;

    public static Singleton3 getInstance() {
        if (s == null)
            synchronized (Singleton3.class) {
                /* 第三种方案对  对二种方法的改进 */
                if (s == null) {
                    s = new Singleton3();
                }
            }
        return s;
    }

    public void print() {
        System.out.println("测试方法2!");
    }
}
// 4: 为了解决第三种方案的缺陷,  咱们须要禁止代码重排. 由此而生第四种方案, 这个应该是最完美的方案了.
class Singleton4 {
    private Singleton4() {
    }

    /* 第四种方案对第三种的优化 */
    private static volatile Singleton4 s;

    public static Singleton4 getInstance() {
        if (s == null)
            synchronized (Singleton4.class) {
                /* 第三种方案对  对二种方法的改进 */
                if (s == null) {
                    s = new Singleton4();
                }
            }
        return s;
    }

    public void print() {
        System.out.println("测试方法2!");
    }
}

使用饿汉式配合类装载机制,也能够实现懒加载和线程安全,以及高效。设计模式

public class Singleton {

    private Singleton() {}

    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

类加载器加载类的时候,会将静态属性直接初始化。 经过这里类加载器的特性, 咱们能够作到线程安全。 经过内部类的方式,实现懒加载。安全

相关文章
相关标签/搜索