a、单例模式:单例是最简单的很常用的一种设计模式,保证了一个类在内存中只能有一个对象。
思路:
1) 如果其他程序能够随意用new创建该类对象,那么就无法控制个数。因此,不让其他程序用new创建该类的对象。
2) 既然不让其他程序new该类对象,那么该类在自己内部就要创建一个对象,否则该类就永远无法创建对象了。
3) 该类将创建的对象对外(整个系统)提供,让其他程序获取并使用。
步骤:
1) 将该类中的构造函数私有化。
2) 在本类中创建一个本类对象。
3) 定义一个方法,返回值类型是本类类型。让其他程序通过该方法就可以获取到该类对象。
1、饿汉式:在类造成之初就新建了一个对象,并且将构造方法设置成私有的,因此外界无法通过new对象的方式过的实例,只能通过getInstance()的方法获得对象实例。
<span style="font-size:14px;">package pattern.singleton.one; public class TestSingle { /** * @param args */ public static void main(String[] args) { Single s1=Single.getInstance(); Single s2=Single.getInstance(); System.out.println(s1==s2); } } class Single { /** * 饿汉式 */ private static final Single s=new Single(); private Single(){ } public static Single getInstance(){ return s; } } </span>2、懒汉式:与饿汉式不同的是,要在外界调用getInstance()方法的时候才会new出一个对象,这就相当于有延迟。
public class Single2 { /** * 懒汉式 */ private static Single2 s=null; private Single2(){ } public static Single2 getInstance(){ if (s==null){ s=new Single2(); } return s; } }这样子写的懒汉式有缺陷,比方说把它放到多线程环境下去的话,会出现多个线程同时到达if(s==null)这里进行判断,那么就会产生多个对象,就违背了单例只产生一个对象的本意了。要解决的话我们要想到在getInstance()前面加synchronized 互 斥锁。如下:
<pre name="code" class="java">public class Single2 { /** * 懒汉式 */ private static Single2 s=null; private Single2(){ } public static synchronized Single2 getInstance(){ //synchronized互斥锁,只能一个一个地拿,防止线程多个拿到相同实例 if (s==null){ s=new Single2(); } return s; } }b、单例变形---多例(单例加缓存)
import java.util.HashMap; import java.util.Map; public class A { private static final Map<String, A> map= new HashMap<String, A>(); public static A getInstance(String key){ A a = map.get(key); if(a==null){ a = new A(); map.put(key, a); } return a; } }2) 单例变形——多例模式
import java.util.HashMap; import java.util.Map; public class A { //容器 private static final Map<Integer, A> map = new HashMap<Integer, A>(); private static int num=1;//代表池中目前将要被使用的对象的序号 private static final int MAX=4;//控制容器中所能使用对象的总个数 public static A getInstance(){ A a = map.get(num); if(a==null){ a = new A(); map.put(num, a); } num++; if(num>MAX){ num = 1; } return a; } }