zoukankan      html  css  js  c++  java
  • 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;     

          }    

    }  

     
     
  • 相关阅读:
    SPOJ SAMER08A
    SPOJ TRAFFICN
    CS Academy Set Subtraction
    CS Academy Bad Triplet
    CF Round 432 C. Five Dimensional Points
    CF Round 432 B. Arpa and an exam about geometry
    SPOJ INVCNT
    CS Academy Palindromic Tree
    身体训练
    简单瞎搞题
  • 原文地址:https://www.cnblogs.com/Spirit612/p/4772487.html
Copyright © 2011-2022 走看看