美文网首页
理解单例模式

理解单例模式

作者: 梦的飞翔_862e | 来源:发表于2018-11-19 11:28 被阅读0次
    概念理解

    单例模式是最简单的设计模式之一,简单理解就是一个类在整个系统运行环境中只有一个实例。这是一种创建型模式,典型的特点是构造器私有化,然后提供一个静态公共 方法获取实例。创建单例饿汉式(类加载时就创建),懒汉式(第一次使用时创建)。

    饿汉式:

    实现非常简单,在声明属性中直接创建,这种方式是线程安全的,只是可能会造成空间的浪费(创建了却没有地方使用)。

    //非懒加载,线程安全,一般推荐这种方式
    public class ChocolateFactory {
        private boolean empty;
        private boolean boiled;
        private static ChocolateFactory INSTANCE = new ChocolateFactory();
        private ChocolateFactory() {
            this.empty = true;
            this.boiled = false;
        }
        public static ChocolateFactory getInstance(){
            return INSTANCE;
        }
    }
    
    懒汉式:

    懒汉式即在第一次使用的时候创建实例,这里提供了一种线程不安全的和三种线程安全的实现方式

    public class ChocolateFactory {
        private boolean empty;
        private boolean boiled;
    
        private static ChocolateFactory INSTANCE = null;
    
        private ChocolateFactory() {
            this.empty = true;
            this.boiled = false;
        }
    
        //线程不安全
        public static ChocolateFactory getInstance() {
            if (INSTANCE == null) {
                INSTANCE = new ChocolateFactory();
            }
            return INSTANCE;
        }
    
        //线程安全
        public synchronized static ChocolateFactory getInstanteThreadSec() {
            if (INSTANCE == null) {
                INSTANCE = new ChocolateFactory();
        }
            return INSTANCE;
        }
    }
    

    在方法上加锁,虽然实现了线程安全,但是当线程并发量大的时候,会造成排队浪费时间的现象,因此使用双重锁机制比较好。

    public class ChocolateFactory {
        private boolean empty;
        private boolean boiled;
    
        private  volatile static ChocolateFactory INSTANCE= null;
    
        private ChocolateFactory(){
            this.empty=true;
            this.boiled=false;
        }
    
        public static ChocolateFactory getInstante(){
            if(INSTANCE==null){
                synchronized (ChocolateFactory.class){
                    if(INSTANCE==null){
                        INSTANCE = new ChocolateFactory();
                    }
                }
            }
            return INSTANCE;
        }
    }
    

    还有一种方式是使用内部类,是基于饿汉式的一种改造

    public class ChocolateFactory {
    
        private boolean empty;
        private boolean boiled;
    
        private ChocolateFactory() {
            this.empty = true;
            this.boiled = false;
        }
    
        //线程安全且是懒加载的
        public static class ChocolateFactoryHolder {
            private volatile static ChocolateFactory INSTANCE = new ChocolateFactory();
        }
        public static ChocolateFactory getInstance() {
            return ChocolateFactoryHolder.INSTANCE;
        }
    }
    
    volatile

    volatile一种轻量级的同步机制,一个线程共享变量(静态变量)使用volatile修饰,表示这个变量是内存可见性,即一个线程修改了改变量,会立马通知另外的线程。
    实际上,内存共享变量的写入和对另外线程的可见,都是通过java内存模型(JMM)控制的。共享变量存储在主内存中,每个线程都有自己的本地内存,存有使用到的主内存的副本拷贝,线程对变量的操作,都是在本地内存中进行,如果需要及时同步到主内存中,需要volatile关键字修饰。
    完整代码实例参见https://github.com/jxl198/designPattern/tree/master/singleton

    相关文章

      网友评论

          本文标题:理解单例模式

          本文链接:https://www.haomeiwen.com/subject/kblofqtx.html