java 设计模式2--单例模式6种

单例模式--作用节省不必要的内存开销,若程序从头到尾仅需一个保存相关状态的对象实例

                                   就不必每次都创建新的对象!(于是在内里面封装一个方法专门来管理此对象

                                   使其成为单例的类)

单例模式--弊病1,在多个虚拟机和分布技术的系统中,应该避免使用存在状态的单例模式,

因为一个有状态的单例类,在不同虚拟机上,各个单例对象保存的状态很可能是不一样的

         2, 不同的类加载器会使用不同的命名空间(namespace)来区分同一个类,

因此,单例类在多加载器的环境下会产生多个单例对象

                                    3,  为了使一个单例类变成可串行化的,仅仅在声明中添加“implements

Serializable”是不够的。因为一个串行化的对象在每次返串行化的时候,都会创建一个新的对象,

而不仅仅是一个对原有对象的引用。为了防止这种情况,可以在单例类中加入 readResolve 方法

(具体情况请参考《Effective Java》一书第 57 条建议,另外,对象的串行化并不仅局限于上述方式,

还存在基于 XML 格式的对象串行化方式)

在eclipse 中开发,结构如下:6种单例模式, 一个测试类


单例模式---第一大类【使用现成对象】:1,  枚举实现的单例(简练,实用,美观)

//枚举实现--单例模式
public enum Singleton1_enum {
	OBJ;	
	public static void printInstance(){
		System.out.println(OBJ.hashCode());//查看内存地址
	}
}
单例模式---第一大类【使用现成对象】:2,   饿汉模式( 比较适合java的)
//饿汉模式
public class Singleton1_hungry {
	//私有静态变量,只在类加载时初始化赋值【只在单个类加载器环境下,是单例的】
	private  static Singleton1_hungry single=new Singleton1_hungry();
	private Singleton1_hungry(){ }//私有构造器
	
	public static Singleton1_hungry  getInstance(){
		return single;
	}
}

单例模式---第一大类【使用现成对象】:3,  静态内部类实现的单例

//使用静态内部类
public class Singleton1_staticInnerClass {
	//私有构造器
	private Singleton1_staticInnerClass(){}
	
	//外部获取实例的接口:
	public static Singleton1_staticInnerClass getInstance(){
		return Inner.singleton;
	}

	//静态内部类: 负责创建外部类实例
	private static class Inner{
		private static Singleton1_staticInnerClass singleton=new Singleton1_staticInnerClass();
}
}

单例模式---第二大类【临时创建对象】: 1,   懒汉模式 

//懒汉模式
public class Singleton2_lazy {
	private static  Singleton2_lazy single;
	private  Singleton2_lazy(){  }
					//同步整个方法:防止多线程并发访问异常
	public synchronized static  Singleton2_lazy getInstance(){
		if(single==null){
			single= new  Singleton2_lazy();
		}
		return single;
	}
}

单例模式---第二大类【临时创建对象】: 2,   双重校验加锁 实现单例 

//使用valatile 关键字, 同步并双重验证
public class Singleton2_doubleCheck {
	private volatile  static Singleton2_doubleCheck single;
	
	private Singleton2_doubleCheck(){System.out.println("构造器。。。");}
	
	public static Singleton2_doubleCheck getInstance(){
		if (single==null){
			synchronized (Singleton2_doubleCheck.class){ //初次为null时,锁定该类,进入下一步验证
					if(single==null){
						single=new Singleton2_doubleCheck();
					 }/**   当初次为null时,若进入2个线程,
						 则锁定一个后直到该线程退出锁(创建了对象),
						第二个线程接到锁,再次判断null为false, 退出锁return null;
						*/
			}//sychronized
		}//single==null
		
		return single;
	}
} 

单例模式---第三大类【HashMap注册表管理对象】:  可继承的单例实现(构造器protected) 

//父类--单例类
//构造器protected,  自己管理HashMap对象注册表,可以被子类继承实现多态
public class Singleton3_protectedConstructor {
		//存放键值对:(“name”,对象实例)
	  private static Map<String,Singleton3_protectedConstructor> map=new HashMap<>();
	  	//泛型:用于管理对象实例,限定存储类型,避免强制类型转换
	   private static Singleton3_protectedConstructor  single;
	   protected Singleton3_protectedConstructor(){  }
	   
	   public static Singleton3_protectedConstructor getInstance(String name){
		   //判断:要获取的是什么 父类?子类?
		   if(name==null){
			   name="Singleton3_protectedConstructor ";//默认获取父类的--单例对象
		   }
		   
		   //判断:map容器中,是否已存在这样的对象--无则创建并添加
		  if( map.get(name)==null){
			    try{
			    	single=(Singleton3_protectedConstructor ) Class.forName(name).newInstance();
			    	map.put(name, single);
			    }catch(Exception e){
			    	e.printStackTrace();
			    }
		  }		  
		 return map.get(name); //从容器里:取出该对象
	   }
	   //一般方法:用于测试多态
	   public void say(){System.out.println("this is father class--singleton class");}
}
//子类
class Son extends Singleton3_protectedConstructor {
	 public  Son(){ }//构造器
	
	public static Son getInstance(){//获取对象实例
		return (Son) Singleton3_protectedConstructor.getInstance("Son");
	}
	//一般方法:用于测试多态
	public void say(){System.out.println("this is son class");}
}

测试结果:            

public class SingletonTest {
	public static void main(String[] args) {
		//创建对象---验证静态内部类单例
	/**	Singleton1_staticInnerClass s= Singleton1_staticInnerClass.getInstance();
		Singleton1_staticInnerClass s2= Singleton1_staticInnerClass.getInstance();
		
		System.out.println(s);//单例模式.Singleton@106d69c
		System.out.println(s2);//单例模式.Singleton@106d69c
		System.out.println(s.hashCode()+"--"+s2.hashCode());//17225372--17225372
	*/	
		//验证--双重验证加锁单例
		/**Single_doubleCheck single=Single_doubleCheck.getInstance();
		Single_doubleCheck single2=Single_doubleCheck.getInstance();
		
		System.out.println(single.hashCode()+"--"+single2.hashCode());//17225372--17225372
		System.out.println(single+"--"+single2);
		//单例模式.Single_doubleCheck@106d69c--单例模式.Single_doubleCheck@106d69c
	          */
		
		//创建对象---验证枚举实现的单例
		/**Singleton_enum single=Singleton_enum.OBJ;
		Singleton_enum single2=Singleton_enum.OBJ;
			
		single.printInstance();		  //原地址 17225372
		System.out.println(single.hashCode());//实例1地址17225372
		System.out.println(single2.hashCode());//实例2地址17225372 */
		
		//创建对象---验证饿汉模式
		/**Singleton_hungry single=Singleton_hungry.getInstance();
		Singleton_hungry single2=Singleton_hungry.getInstance();
		
		System.out.println(single.hashCode());//实例1地址17225372
		System.out.println(single2.hashCode());//实例1地址17225372
		System.out.println(single+"--"+single2);
		//单例模式.Singleton_hungry@106d69c--单例模式.Singleton_hungry@106d69c
           */
		
		//创建对象---验证可以继承的单例模式
		String name="单例模式.Singleton3_protectedConstructor";//单例类名:包名.类名
		Singleton3_protectedConstructor single=new Son().getInstance(name) ;
		Singleton3_protectedConstructor single2=new Son().getInstance(name) ;
		Singleton3_protectedConstructor son=new Son().getInstance("单例模式.Son") ;
		
		System.out.println(single.hashCode());//17225372
		System.out.println(single2.hashCode());//17225372
		//测试多态
		single.say();//this is father class--singleton class
		single2.say();//this is father class--singleton class
		son.say();   //this is son class
	}
}

猜你喜欢

转载自blog.csdn.net/eyeofeagle/article/details/79364660