设计模式之单例模式

定义:保证一个类再运行期间只有一个实例对象,并提供一个访问它的全局访问方法。
单例模式的范围:是一个ClassLoader极其子类的范围,每被ClassLoaser加载一次就会创建一次。
饿汉式:

public class Singleton {
	private Singleton() {
	}

	private static Singleton instance = new Singleton();

	public static Singleton getInstance() {
		return instance;
	}
}

懒汉式:

public class Singleton {
	private Singleton() {
	}

	private volatile static  Singleton instance = null;

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

不论饿汉式还是懒汉式,都需要私有化构造方法。饿汉式在类加载的时候就创建实例;懒汉式是在调用方法的是时候才去判断时否创建实例。
以上懒汉示例应用了双重检查机制,避免多次判断,节省时间。为了在多线程环境下仍可以实现单例的目标,应用了synchronized 同步创建过程。为了避免在多线程环境中,出现instance不为null,但是instance还没初始化完成的情况,使用volatile 关键字修饰instance 。

单例模式体现的设计思想:
1.延迟加载思想(懒汉式)
2.缓存思想 (懒汉式)
(1). 定义一个缓存数据的容器
(2). 缓存中存取数据,先从容器取值,再判断时否有值,有值直接返回,如果没有就获取相应的数据,然后放到容器中,再返回。
缓存的实现示例:

public class JavaCache {
	private Map<String, String> map = new HashMap<>();
	
	public Object getValue(String key) {
		String value = map.get(key);
		//value不存在,所有先取值,然后放到容器中
		if(value == null) {
			//此处仅仅是取值示例
			value = key + "value";
			map.put(key, value);
		}
		return value;
	}
}

单例模式的应用场景示例:读取配置文件的类,一般在系统初始化的时候有一个示例进行配置初始化就可以了,如果存在多个实例,多次加载配置文件,会造成系统资源的浪费。
配置文件:config.properties

paramA=xx
paramB=yy

读取配置文件的类:AppConfig.properties

public class AppConfig {
	/**
	 * 私有化构造器,并在创建实例的时候,加载配置文件
	 */
	private AppConfig() {
		readConfig();
	}
	
	private static AppConfig instance = new AppConfig();
	
	public static AppConfig getInstance() {
		return instance;
	}
	
	private String paramA;
	private String paramB;
	public String getParamA() {
		return paramA;
	}

	public String getParamB() {
		return paramB;
	}
	/**
	 * 读取配置文件,一般只需加载一次即可
	 * @throws IOException 
	 */
	private void readConfig()  {
		Properties p = new Properties();
		InputStream in = null;
		System.out.println("1111");
		try {
			in = AppConfig.class.getResourceAsStream("config.properties");
			p.load(in);
			this.paramA = p.getProperty("paramA");
			this.paramB = p.getProperty("paramB");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
}

单例模式的本质是:控制实例的数量。
扩展:如何控制类的特定数量的实例?

public class SingletonExtend {
	private SingletonExtend() {
	};

	// 存放创建的实例的容器
	private static Map<String, SingletonExtend> map = new HashMap<>();
	// 记录当前实例的位置
	private static int num = 1;
	//缺省key值前缀
	private static final String DEFAULT_KEY = "cache";
	// 最大的实例数量
	private static final int maxNum = 3;

	public static SingletonExtend getInstance() {
		String key = DEFAULT_KEY + num;
		SingletonExtend singletonExtend = map.get(key);
		if (singletonExtend == null) {
			map.put(key, new SingletonExtend());
		}
		if (num++ >= maxNum)
			num = 1;
		return map.get(key);
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值