码迷,mamicode.com
首页 > 其他好文 > 详细

ooad单例模式-Singleton

时间:2015-08-31 11:44:02      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:

                                            单例模式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;     

      }    

}  

 
 

ooad单例模式-Singleton

标签:

原文地址:http://www.cnblogs.com/Spirit612/p/4772487.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!