当前位置:编程学习 > JAVA >>

设计模式--创建模式--单例模式--java

Intent:
      •Ensurea class only has one instance, and provide a global point of access to it.
       确保一个类只有一个实例,并且提供一个全局的引用来获取它。
Applicability
     •theremust be exactly one instance of a class, and it must be accessible to clientsfrom a well-known access point.
      •仅有一个实例,并且客户端需要从一个众所周知的访问点来获取它。
     •whenthe sole instance should be extensible bysubclassing, and clients should be able to use an extended instancewithout modifying their code.
     •当这个唯一实例应该通过子类化可扩展的,并且客户端应该无需更改代码就能使用一个扩展的实例时。
Consequences 
     •Controlled access to sole instance
     •控制实例访问
     •Reduced name space
     •减少名空间
     •Permits refinement of operations and representation
     •允许对操作和表示的精化
     •Permits a variable number of instances
     •允许可变数数目的实例
     •More flexible than class operations
     •比类操作更灵活
UML
Code
 饿汉方式实现。当隐式加载Singleton,变初始化singleton。
[java]  
/** 
 * 饿汉 
 *  
 * @author changsheng 
 */  
public class Singleton {  
  
    static private final Singleton singleton = new Singleton();  
  
    private Singleton(){  
    }  
  
    static public Singleton getInstance() {  
        return singleton;  
    }  
}  
利用反射破坏单例
[java] 
@SuppressWarnings("unchecked")  
    public static void reflect() throws InstantiationException,  
            IllegalAccessException, InvocationTargetException {  
        Class<Singleton> clazz = Singleton.class;  
  
        /* get constructors info */  
        Constructor<?>[] methods = (Constructor<Singleton>[]) clazz  
                .getDeclaredConstructors();  
        for (int i = 0; i < methods.length; i++) {  
            System.out.println(methods[i]);  
        }  
  
        methods[0].setAccessible(true);  
  
        Singleton s1 = (Singleton) methods[0].newInstance();  
        Singleton s2 = (Singleton) methods[0].newInstance();  
        System.out.println(s1 == s2);  
    }  
 
懒汉实现。当显式调用Singleton2.getInstance才初始化singleton2.
[java]  
/** 
 * 懒汉 
 * @author changsheng 
 * 
 */  
public class Singleton2 {  
      
    static private Singleton2 singleton2;  
      
    private Singleton2(){  
          
    }  
        //sychronized关键字不是必须的,根据需求而定。     
    static synchronized public Singleton2 getInstance(){  
        if(singleton2 == null){  
            singleton2 = new Singleton2();  
        }  
        return singleton2;  
    }  
}  
 
懒汉和饿汉的选择主要以单例实例化是否耗时为衡量标准。
 
双重检查机制,主要解决多线程并发访问的效率。具体并发知识可查阅书籍Java Concurrency in practice。
[java]  
class Singleton3 {  
    static volatile private Singleton3 singleton3;  
    /*此处为什么要使用volatile关键字?一旦线程改变了singleton3,其他线程可立即可见*/  
    private Singleton3(){  
          
    }  
    /** 
     * 为什么要使用双重检查机制?避免多个线程排队问题   */  
    static public Singleton3 getInstance(){  
        if(singleton3 == null){  
            synchronized (Singleton3.class) {  
                if(singleton3 == null)  
                    singleton3 = new Singleton3();  
            }  
        }  
        return singleton3;  
    }  
}  
 
通过序列化来破坏单例。
[java]  
public class Singleton3 implements Serializable {  
    private static final long serialVersionUID = 1L;  
    static private final Singleton3 s = new Singleton3();  
      
    private Singleton3(){  
          
    }  
      
    static public Singleton3 getInstance(){  
        return s;  
    }  
      
    public static void main(String[] args) throws IOException, ClassNotFoundException {  
        Singleton3 s1 = Singleton3.getInstance();  
        Singleton3 s2 = Singleton3.getInstance();  
          
        System.out.println(s1 == s2);  
          
          
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(bos);  
        oos.writeObject(s1);  
      
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
        ObjectInputStream  ois = new ObjectInputStream(bis);  
<
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,