解决:保证了一个类在内存中只能有一个对象。

思路:

    1、如果其他程序能够随意用new创建该类对象,那么就无法控制个数。因此,不让其他程序用new创建该类的对象。
    2、既然不让其他程序new该类对象,那么该类在自己内部就要创建一个对象,否则该类就永远无法创建对象了。

    3、该类将创建的对象对外(整个系统)提供,让其他程序获取并使用。

步骤:

    1、将该类中的构造函数私有化。
    2、在本类中创建一个本类对象。
    3、定义一个方法,返回值类型是本类类型。让其他程序通过该方法就可以获取到该类对象。

饿汉式:

/**
 * Time:2018/4/13
 * Description:单例---饿汉模式
 * @author 宋进宇
 */
public class HungryManModel {
	//加载类模板时就加载实例。
	private static final HungryManModel HUNGRY_MAN_MODEL = new HungryManModel();
	//私有化构造方法,以便实现单例
	private HungryManModel(){
	}
	//获取实例
	public static HungryManModel getInstance(){
		return HUNGRY_MAN_MODEL;
	}
}

懒汉式:

/**
 * Time:2018/4/13
 * Description:单例---懒汉模式
 * @author 宋进宇
 */
public class LazyManModel {
	//加载类模板时不加载实例,到调用获取实例方法时,在实例化对象
	private static LazyManModel lazyManModel = null;
	//私有化构造函数,以便实现单例
	private LazyManModel(){
	}
	//提供一个获取实例的方法
	//★★★在多线程的情况中需要用 synchronized 关键字 对该方法加锁。
	public synchronized static LazyManModel getInstance() {
		//如果是第一次调用获取实例方法,则创建一个对象,否则直接返回lazyManModel
		if (lazyManModel==null) {
			lazyManModel = new LazyManModel();
		}
		return lazyManModel;
	}
}

单例变形---多例

不限个数“单例+缓存”:

    缓存在编程中使用很频繁,有着非常重要的作用,它能够帮助程序实现以空间换取时间,通常被设计成整个应用程序所共享的一个空间,现要求实现一个用缓存存放单例对象的类。
    说明:该缓存中可以存放多个该类对象,每个对象以一个key值标识,key值相同时所访问的是同一个单例对象。

import java.util.HashMap;
import java.util.Map;
/**
 * Time:2018/4/14
 * Description:多例---不限个数
 * @author 宋进宇
 */
public class MultiCase {
	//一加载类模板时,就创建一个map容器
	private static Map<String, MultiCase> multiCases = new HashMap<String, MultiCase>();
	//看项目需求,是否需要封掉构造函数,本例采用封掉构造函数
	private MultiCase(){
	}
	//对外提供一个可以通过key来获取一个对象实例
	public static MultiCase getInstanceByKey(String key) {
		//先通过key从容器中获取一个值
		synchronized (key) {
			MultiCase value = multiCases.get(key);
			//如果是null说明该对象还没被实例化,即第一次通过这个key值来获取实例
			if (value==null) {
				value = new MultiCase();
				multiCases.put(key, value);
			}
			return value;
		}
	}

}

限制个数“单例+缓存+控制实例个数”:

    把上面缓存的单例实现,做成一个能够控制对象个数的共享空间,供整个应用程序使用。在缓存中维护指定个数的对象,每个对象的key值由该类内部指定,有外部请求时直接返回其中一个对象出去。
    说明:相当于维护一个指定数量的对象池,当请求个数超过控制的总数时,开始循环重复使用 。

import java.util.HashMap;
import java.util.Map;
/**
 * Time:2018/4/14
 * Description:多例---不限个数
 * @author 宋进宇
 */
public class MultiCase2 {
	//一加载类模板时,就创建一个map容器
	private static Map<Integer, MultiCase2> multiCase2s = new HashMap<Integer, MultiCase2>();
	//设置该容器中最多的实例个数
	private final static int MAX = 3;
	private static int num = 0;//已使用个数
	//封掉构造函数
	private MultiCase2(){
	}
	//对外提供一个可以获取一个对象实例的方法
	public static MultiCase2 getInstance(){
		MultiCase2 value = multiCase2s.get(num);
		if (value==null) {
			value = new MultiCase2();
			multiCase2s.put(num, value);
		}
		num++;
		if (num>MAX) {
			//根据项目来控制,本例直接清0
			num = 0;
		}
		return value;
	}
}