单例模式
常见设计模式
工厂模式,代理模式,模板方法模式,责任链模式,单利模式
项⽬⼿写代码⽤得⽐较多的,⼀般就模板⽅法模式、责任链模式、策略模式、单例模式吧
单例模式
即某个类在整个系统中只能有一个实例对象可被获取和使用的代码模式。
有一些对象只需要一个,如:线程池、缓存、注册表对象。也只能有一个
给了一个全局访问点,和全局变量一样,但是没有全局变量的缺点(全局变量需要一开始就创建好对象,单例模式可以在需要的时候才创建)
如:代表 JVM 运行环境的 Runtime 类
要点
1)某个类只能有一个实例(构造器私有化)
2)它必须自行创建实例( 含有一个该类的静态变量来保存这个唯一的实例)
3)它必须自行向整个系统提供这个实例(对外提供获取该类实例对象的方式直接暴露,用静态变量声明的方法获取)
优点
- 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
- 2、避免对资源的多重占用(比如写文件操作)。
缺点
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景
- 要求生产唯一序列号。
- WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
- 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
实现
饿汉式
public class Single { // 饿汉式:直接实例化 private static Single single = new Single(); // 构造私有 private Single(){} public static Single getinstance(){ return single; } }
简单懒汉式
/** * 简单懒汉式 方法加锁 */ class Single2{ private static Single2 single2 = null; private Single2() { } // 需要的时候才会初始化 public static synchronized Single2 getinstance(){ if(single2 == null){ single2 = new Single2(); } return single2; } }
DCL双重检验加锁(进阶懒汉式)
/** * DCL懒汉式 */ class Single3{ /** * volatile 防止指令重排导致线程不安全 */ private static volatile Single3 single3 = null; public Single3() { } public static Single3 getinstance() { if(single3 == null) { synchronized (Single3.class) { if (single3 == null) { single3 = new Single3(); } } } return single3; } }
静态内部类(优雅懒汉式)
/** * 静态内部类 懒汉式 */ class Single4 { private Single4(){} //使用静态内部类的方式实现懒加载(一定线程安全) private static class LazyHolder{ private static final Single4 singleton = new Single4(); } public static final Single4 getInstance() { return LazyHolder.singleton; } }
枚举
/** * 枚举 */ enum Single5{ /** * 单例 */ SINGLETON }
作者: deity-night
出处: https://www.cnblogs.com/deity-night/
关于作者:码农
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(***@163.com)咨询.