关于设计模式:单例模式

6次阅读

共计 2351 个字符,预计需要花费 6 分钟才能阅读完成。

利用场景

封装一些罕用的工具类,保障整个利用罕用的数据对立
保留一些共享数据在内存中,其余类随时能够读取。
创建对象耗时或者消耗资源过多,但又须要频繁用到;
须要频繁的进行创立和销毁的对象;
留神:如果写成单例模式就不要用 spring 注入了,spring 注入默认单例,两者反复
7 种形式

饿汉式

线程平安
public class Singleton {private static final Singleton instance = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {return instance;}
}

线程平安,类加载的时候实例化,意思就是在初始化 instance 的时候就 new 了,所以导致资源节约(求全责备的说)

懒汉式 - 线程不平安

线程不平安

public class Singleton {

private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {if (instance == null) {instance = new Singleton();
    }
    return instance;
}

}
首次我调用 getInstance,那么就会进行类加载,这时候 instance 援用没被初始化。
而后进行判断空后,给 instance 援用初始化一个对象。
下次调用 getInstance 因为是不是空,间接返回。
疑难:我调用 getInstance 后,都会返回一个对象。饿汉式只是说初始化的时候就 new 了对象,而我这做了判断再 new,本质上都把对象 new 了。那么懒汉式节俭资源体现在哪?


体现在你调用类的其它办法的时候,它不会 new(实例化)对象!

上代码!

懒汉式 - 同步办法

线程平安,同步办法
public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();
        }
        return instance;
    }
}

线程平安,但效率低下!

懒汉式,双重检测

线程平安,同步代码块

public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

兼顾效率和线程平安,能够用。然而性能不高

动态外部类(举荐)

线程平安

public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
    private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();
    }
}

业务这种够用,线程平安 + 懒加载

枚举

线程平安
public enum Singleton {INSTANCE;}

晓得就行,线程平安,防反射,防反序列化。其它形式不防!

枚举懒加载

public class ThreadPoolUtil {

private enum innerEnum {
    INSTANCE;
    private final ThreadPoolExecutor executor;
    private final ThreadPoolUtil threadPoolUtil;
    innerEnum() {ThreadPoolExecutor.CallerRunsPolicy policy = new ThreadPoolExecutor.CallerRunsPolicy();
        executor = new ThreadPoolExecutor(0,
                Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>(),
                policy
        );
        threadPoolUtil = new ThreadPoolUtil();}
    private ThreadPoolExecutor getThreadPool() {return executor;}
    private ThreadPoolUtil threadPoolUtil() {return threadPoolUtil;}
}
public static ThreadPoolUtil getInstance() {return innerEnum.INSTANCE.threadPoolUtil();
}
public ThreadPoolExecutor getThreadPool() {return innerEnum.INSTANCE.getThreadPool();
}

}
这部分拿不准,先放在这里。所以说枚举到底是不是懒加载,是的话又例子论证吗?网上说法不一,搞不懂
最初再宣传一波,我的个人主页:个人主页,在这里你将播种我的成长知识库,不限于后端、前端、生存等知识库哟~
期待和老兵单干?想晓得我能为你做什么?点击这里吧!我能做什么?

                                                                                                                                     转载单干分割老兵,擅自盗用必究!
正文完
 0