设计模式——单例模式

单例模式:创建型模式,保证一个类只有一个实例,并且提供一个访问该实例的全局访问点

饿汉式:线程安全,调用效率高,不能延时加载

public class SingtonDemo {

    //私有构造方法,这样外面就不能创建对象了
    private SingtonDemo() {

    }

    // 被static修饰的变量,属于类本身(可以通过类名加 . 进行访问),不属于某一个对象
    // 当该类的static变量被修改时,所有对象的static成员变量也会被修改
    private static SingtonDemo singtonDemo = new SingtonDemo();

    //提供一个获取该对象的方法,实现每次获取都是这一个对象
    public static SingtonDemo getInstance() {
        return singtonDemo;
    }
}

class SingtonDemoTest {
    public static void main(String[] args) {
        SingtonDemo singtonDemo = SingtonDemo.getInstance();
        SingtonDemo singtonDemo1 = SingtonDemo.getInstance();
        System.out.println(singtonDemo == singtonDemo1); //true
    }
}

懒汉式:线程安全,调用效率不高,能延时加载

饿汉式的缺点,如果在程序运行很长时间还没有用到初始就加载的对象,会导致资源的浪费,懒汉式来解决用的时候再加载

public class SingtonDemo {

    //私有构造方法,这样外面就不能创建对象了
    private SingtonDemo() {

    }

    private static SingtonDemo singtonDemo;

    //提供一个获取该对象的方法,实现每次获取都是这一个对象,为防止多线程创建多个对象用synchronized
    public static synchronized SingtonDemo getInstance() {
        if(singtonDemo == null) {
            singtonDemo = new SingtonDemo();
        }
        return singtonDemo;
    }
}

class SingtonDemoTest {
    public static void main(String[] args) {
        SingtonDemo singtonDemo = SingtonDemo.getInstance();
        SingtonDemo singtonDemo1 = SingtonDemo.getInstance();
        System.out.println(singtonDemo == singtonDemo1); //true
    }
}

双重检查锁(DCL懒汉式)

class SingtonDemo {

    private SingtonDemo() {
    }

    private volatile static SingtonDemo singtonDemo;

    public static SingtonDemo getInstance() {
        if(singtonDemo == null) {
            synchronized (SingtonDemo.class) {
                if (singtonDemo == null) {

                    // 由于这个new操作非原子性
                    // 1、申请内存空间,2、初始化对象,3、将该对象放到内存空间中
                    // 正常执行顺序时123,如果发生了指令重排,可能执行顺序为132
                    // 这样一来,内存空间中就有了未初始化的对象
                    // 当线程A来new对象的时候执行了13,此时,线程B刚好走第一个if
                    // 这样一来,线程B就以为singtonDemo非空,而获得了一个未初始化的对象
                    // 解决方案,给SingtonDemo加volatile关键字,禁止指令重排。
                    singtonDemo = new SingtonDemo();
                    
                }
            }
        }
        return singtonDemo;
    }
}

 

相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页