• 单例模式


    2018-8-5 15:46:48

    单例模式

    使用场景

    一个国家只需要一个皇帝。

    单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个好的方法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。------《设计模式:可复用面向对象软件的基础》

    例如,读取配置文件信息的类,这个类只需要在应用启动的时候读取一次就行,以后就从这个类获取相关配置信息就行。

    好处

    尽可能的节约内存空间,减少无谓的GC消耗,并且使应用可以正常运作。

    一个类只有一个实例,每次使用时,都返回唯一的实例。相对于那些需要使用类就要new一个对象来说,初始化时分配内存空间,不使用了还要垃圾回收,简直是节俭的代表。

    五种写法

    一、懒汉式

    线程不安全:

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

    实例唯一:

    1、私有化静态实例,带有static关键字的属性在每一个类中都是唯一的,带有private关键字的属性必须提供访问实例的方法。
    2、私有化构造函数,限制客户端随意创建实例,保证没有其他实例被创建。
    3、提供一个访问该实例的方法getInstance,这个方法必须是静态的,因为我们的实例是静态的。
    4、只初始化一次,当唯一实例为null的时候,其他时候直接返回实例

    线程安全:

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

    同步getInstance访问方法,效率不高。

    二、饿汉式(线程安全)

    public class Singleton {
    	private static Singleton singleton = new Singleton();
    	private Singleton() {}
    	public static Singleton getInstance() {
    		return singleton;
    	}
    }
    

    简单易理解且安全,我喜欢这种,虽然有时即使没有使用到它也会被实例化出来,但是喜欢就要喜欢它的所有,hh。

    三、双重锁定

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

    只同步创建实例的代码块,而且这个代码块执行的次数不会多,当然经常只有一次,效率比较高。

    四、静态内部类

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

    用内部类保存唯一的实例,另外好处是lazy loading(延迟加载),只有使用时才会实例化。

    五、枚举

    pubic enum Singleton {
    	INSTANCE;
    
    	public void whateverMethod() {}
    }
    

    《Effectiv Java》第二版第3条:用私有构造器或者枚举类型强化Singleton属性 中,说单元素的枚举类型已经成为实现Singleton的最佳方法。

    参考:

    (一)单例模式详解

    单例模式的七种写法

    单例模式五种实现

    2018年8月5日19:28:26

  • 相关阅读:
    vs2012远程调试功能的改进
    【转】SpringBoot处理url中的参数的注解
    通过Maven导出war包时报错:Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project
    【转载】JAVA生成随机数工具类RandomStringUtils详解
    linux centos7 搭建开发环境
    【转载】idea 使用Tomcat 部署war 和 war exploded的区别
    SSM整合文件
    mybatis 数据库properties
    win10 在服务中找不到mysql的解决办法
    idea 创建springmvc项目
  • 原文地址:https://www.cnblogs.com/mingmingcome/p/9426910.html
Copyright © 2020-2023  润新知