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

单例模式

时间:2016-06-10 11:01:08      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

单例模式:一个类有且仅有一个实例,并且自行实例化向整个系统提供。

1.懒汉式:线程不安全(调用时加载实例)

public class Singleton {  

    private static Singleton instance; 

    private Singleton (){}  
  
    public static Singleton getInstance() {  

        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

2.懒汉式:线程安全,但效率较低(调用时加载实例)

public class Singleton {  

    private static Singleton instance;  

    private Singleton (){}  

    public static synchronized Singleton getInstance() { 
 
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

3.饿汉式:线程安全(类装载时加载实例)

public class Singleton {  

    private static Singleton instance = new Singleton();  

    private Singleton (){}  

    public static Singleton getInstance() {  
    
        return instance;  
    }  
}

4.静态内部类:线程安全(调用时加载实例)

public class Singleton {  

    private static class SingletonHolder {  

        private static final Singleton INSTANCE = new Singleton();  
    }  

    private Singleton (){}  

    public static final Singleton getInstance() {  

        return SingletonHolder.INSTANCE;  
    }  
}

5.枚举:线程安全,防止反序列化重新创建对象

public enum Singleton {  

    INSTANCE;  
    
    public void whateverMethod() {  
    }  
}

6.双重校验锁:线程安全,效率相对更高(调用时加载实例)

public class Singleton {  

    private volatile static Singleton singleton;  

    private Singleton (){}  

    public static Singleton getSingleton() {  
        //检验实例是否存在:不存在才进入同步块
        if (singleton == null) {  

            synchronized (Singleton.class) { 
            //再次检验实例是否存在:不存在才创建新实例
            if (singleton == null) {  
                singleton = new Singleton();  
            }  
            }  
        }  
        return singleton;  
    }  
}

问题1:单例由不同的类加载器加载,便可能存在多个单例类的实例。比如不同servlet使用完全不同的类装载器。

private static Class getClass(String classname) throws ClassNotFoundException {     

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();     
      
    if(classLoader == null)     

        classLoader = Singleton.class.getClassLoader();     
        return (classLoader.loadClass(classname));     
   }     
}

问题2:单例类实现了java.io.Serializable接口,那么这个类的实例就可能被序列化和复原,便会存在多个单例类的实例。

public class Singleton implements java.io.Serializable {   

    public static Singleton INSTANCE = new Singleton();     
      
    protected Singleton() {     
        
    }     

    private Object readResolve() { 

        return INSTANCE;     
    }    
}

总结:懒汉式,饿汉式,静态内部类,枚举,双重检验锁。

一般要先保证线程安全,然后根据实际问题考虑效率的问题。

转自:http://cantellow.iteye.com/blog/838473

单例模式

标签:

原文地址:http://www.cnblogs.com/crazy2016/p/5573261.html

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