设计模式读书笔记-单例模式

2016-08-21
读书笔记
  • 只能产生一个实例对象。实例为静态成员,构造方法为private,静态方法返回惟一实例。
  • 单例类一般不要实现Cloneable接口,若一个类实现了Cloneable接口且实现了clone()方法,那么这个类可以被复制,类复制时不需要调用构造方法。单例将被破坏。
  • 一个单例对象在内存中长久不使用,JVM会认为这个对象是一个垃圾,将会对其进行回收。但若采用J2EE容器或框架级容器(如Spring容器),可以让对象长久驻留内存。
  • spring中每个bean默认均为单例,这样做spring容器可以管理bean的生命周期。若采用非单例模式(如prototype),则bean初始化后的管理交由j2ee容器管理,spring容器不再管理。
  • 代码示例

    • 饱汉式:线程不安全,可通过synchronized来解决

      public class Singleton {
      
          private static Singleton item;
      
          private Singleton(){}
      
          public static Singleton getInstance() {
              if(item==null)
                  item = new Singleton();
              return item;
          }
      }
      
    • 线程安全:

      public class Singleton {
      
          private static Singleton item;
      
          private Singleton(){}
      
          public static Singleton getInstance() {
              if(item==null){
                  synchronized (Singleton.class) {
                      if (item == null) {// Double checked
                          item = new Singleton();
                      }
                  }
              }
              return item;
          }
      }
      
    • 饿汉式

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

多例模式

  • 定义:三个static变量:最大实例数量maxInstanceNum,当前实例编号nowInstanceNum,实例列表instanceList。构造方法为private
  • 一个static代码块:此代码块中生成所有实例,并将其添加到实例列表instanceList中。
  • 一个static方法getInstance:获取0-maxInstanceNum间的一个随机整数random.nextInt(maxInstanceNum),从实例列表instanceList中获取索引为此值的实例。
  • 考虑到多线程环境,可以用Vector代替ArrayList
  • 代码:

    public class Multiton {
    
        private static int maxInstanceNum=10;//最大实例数量
        private static int nowInstanceNum=0;//当前实便编号
        private static List<Multiton> instanceList = new ArrayList<Multiton>();
        private static List<String> instanceNameList = new ArrayList<String>();
    
        static{//把所有的皇帝都产生出来
            for(int i=0;i<maxInstanceNum;i++){
                instanceList.add(new Multiton("皇"+(i+1)+"帝"));
            }
        }
    
        private Multiton(String name) {
            instanceNameList.add(name);
        }
    
        public static Multiton getInstance(){
            Random random = new Random();
            nowInstanceNum = random.nextInt(maxInstanceNum);//随机拉出一个皇帝
            return (Multiton)instanceList.get(nowInstanceNum);
        }
    
        public static void emperorInfo(){
            System.out.println(instanceNameList.get(nowInstanceNum));
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            for(int i=0;i<100;i++){
                Multiton.getInstance();
                System.out.print("第"+(i+1)+"个大臣参拜的是:");
                Multiton.emperorInfo();
            }
        }
    }
    

Kommentare: