您的位置:首页 > 编程语言 > Java开发

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

2018-02-24 19:40 387 查看
单例模式--作用:节省不必要的内存开销,若程序从头到尾仅需一个保存相关状态的对象实例
                                   就不必每次都创建新的对象!(于是在内里面封装一个方法专门来管理此对象
                                   使其成为单例的类)

单例模式--弊病: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;
}
}单例模式-
a749
--第二大类【临时创建对象】: 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
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: