解决:保证了一个类在内存中只能有一个对象。
思路:
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() {//如果是第一次调用获取实例方法,则创建一个对象,否则直接返回lazyManModelif (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) {//根据项目来控制,本例直接清0num = 0;}return value;}
}