• ooad单例模式-Singleton


                                                单例模式Singleton
    主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
    比如建立目录 ,数据库连接都需要这样的单线程操作
    好处在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收
    //实现单例模式
    ①该类的构造器是private 私有的 使其不能被其他类创建(new)
    ②创建一个静态方法 返回该类的对象(唯一)
     
    单例都是五种写法。懒汉,恶汉,双重校验锁,枚举和静态内部类。
    下面是具体书写方式
    package com.Spirit.singleton;

    //饿汉式一(预加载) 不能用于多线程
    /*public class Car {
        
        private static Car c = new Car();
        
        private  Car(){}
        public static Car getInstanse(){
            
            return c;
        }    

    }*/
     
    //饿汉式二  不能用于多线程
    /*
     
    private static class SingletonHolder{  
            /** 
             * 静态初始化器,由JVM来保证线程安全 
             */ 
            private static Singleton instance = new Singleton();  
        }  
        /** 
         * 私有化构造方法 
         */ 
        private Singleton(){  
        }  
        public static  Singleton getInstance(){  
            return SingletonHolder.instance;  
        }  
    }*/
     
    /*
    //(懒汉,线程不安全):
    public class Car{ 
    private static Car car=null;    
    private Car(){}  
      public static Car getInstance() {  
       if (instance == null) {        
    car= new Car();    
    return car; 
    }
    } 
    */

    //懒汉式 (懒加载、延迟加载) 线程安全
        但效率很低,99%情况下不需要同步。
    /*
    public class Car{
        
        private static Car c = null;
        
        private Car(){};
        
      public synchronized static Car getInstanse(){
          
          if(c==null){
             c =  new Car();
          }
            return c;
        }    
    }*/

    //静态内部内
    public class Singleton {  

        private static class SingletonHolder { 

    private static final Singleton INSTANCE = new Singleton();  

    }

    private Singleton (){} 

    public static final Singleton getInstance() { 

    return SingletonHolder.INSTANCE;  

        }  

    }

    //枚举
    public enum Singleton {   
      INSTANCE;    
    public void whateverMethod() { 
     这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,不过,个人认为由于1.5中才加入enum特 性,用这种方式写不免让人感觉生疏,在实际工作中,很少有人这样写。

    //双锁机制(懒加载升级版  在多线程时会出现前一个未做处理,第二个开始加载的错误
    所有多线程时都使用双锁保证加载完成)
    public class Car{
        
    private static Car c = null;
        
        private Car(){};
        
      public  static Car getInstanse(){
          
          if(c==null){
              synchronized (Car.class) {
                  if(c==null){
                  c =  new Car();
                }
          }
        }    
          return c;
    }
     
    }
     
    需注意的问题:

    1.如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,

    例如一些servlet容器对每个servlet使用完全不同的类装载器,这样的话如果有两个servlet访问一个单例类,它们就都会有各自的实例。

    2.如果Singleton实现了java.io.Serializable接口,那么这个类的实例就可能被序列化和复原。

    不管怎样,如果你序列化一个单例类的对象,接下来复原多个那个对象,那你就会有多个单例类的实例。

    //第一种的修复方式:

    private static Class getClass(String classname)      

                                            throws ClassNotFoundException {     

          ClassLoader classLoader = Thread.currentThread().getContextClassLoader();  

       if(classLoader == null)     

      classLoader = Singleton.class.getClassLoader();  

       return (classLoader.loadClass(classname));    

    }   

      } 

    //第二种的修复方式:
    public class Singleton implements java.io.Serializable {     

       public static Singleton INSTANCE = new Singleton();   

      protected Singleton() {     

       }   

      private Object readResolve() {   

      return INSTANCE;     

          }    

    }  

     
     
  • 相关阅读:
    RadGrid Expand/Collapse on Row click
    AutoComplete Textbox with Additional Parameters From Database
    Combobox.Items中添加项Items
    JavaScript 处理字符串(操作字符串)
    用nettiers + svn + resharper + rad + ccNet开发前的准备工作
    Document.location.href和.replace的区别
    .net remoting的事务传播以及wcf分布式事务
    IDA反汇编/反编译静态分析iOS模拟器程序(三)函数表示与搜索函数
    [置顶] 一道有趣的逻辑题
    mini2440uboot移植基本操作指令
  • 原文地址:https://www.cnblogs.com/Spirit612/p/4772487.html
Copyright © 2020-2023  润新知