性价比超高的设计模式——单例模式

为何说单例模式性价比高?
在面试过程当中常常让手撸的一种设计模式,而且被面的频率很是高。重点是这种设计模式很简单!java

个人我的博客(后台建站,Tomcat集群,Redis分布式,nginx,适合初学者)nginx

为何要用单例模式?面试

在开发过程当中,根据需求的不一样,有时可能要求对象实例只能有一个,这时就要使用到了单例模式。设计模式

如:Spring中的bean默认使用的都是单例模式。安全

什么是单例模式?cookie

确保对象只有一个,并提供一个全局访问点。分布式

1、单例模式初探

经典的实现方式:性能

饿汉式线程

public  class Singleton1{
    private static Singleton1 uniqueInstance = new Singleton1();
    private Singleton1() {
        super();
    }
    
    public static Singleton1 getInstance(){
        return uniqueInstance;
    }
}

懒汉式设计

public  class Singleton2{
    private static Singleton2 uniqueInstance = null;
    private Singleton2(){
        super();
    }
    
    public static Singleton2 getSinleton(){
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton2();
        }
        return uniqueInstance;
    }
}

进阶实现方式

双重检查加锁

public class Singleton3{
    private  static volatile Singleton3 uniqueInstance = null;
    private Singleton3 (){
        super();
    }
    
    public static Singleton3 getInstance() {
        if (uniqueInstance == null){
            synchronized (Singleton3.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton3();
                }
            }
        }
        return uniqueInstance;
    }
}

静态内部类

public class Singleton4{
    
    private Singleton4() {
        super();
    }
    private static  class Holder{
        private static final Singleton4 uniqueInstance = new Singleton4();
    }
    
    public static final Singleton4 getInstance(){
        return Holder.uniqueInstance;
    }
}

2、分析与比较

饿汉式: 在类加载时就建立对象,不管是否使用都会建立,天生线程安全。

懒汉式:延迟化实例,在使用时才会建立,线程不安全,相比饿汉式来讲对于资源敏感的对象很重要,能节省系统资源。

双重校验:延迟化实例,线程安全,可是牺牲性能来提高安全。

静态内部类:只有在,内部类在第一次调用Holder.uniqueInstance时才会建立实例,因此也是一种延迟化实例的机制,经过静态内部类只有第一次引用才会被加载,因此是线程安全的;而且经过反射,也没法从外部类获取内部类的属性。因此这种形式,很好的避免了反射入侵。

3、总结

为何进行双重校验?

因为同步范围比较精确,也可能出现安全问题,即在判断为null和加锁之间另外一个线程已经建立了对象,由于使用了volitile关键字保证了对象的可见性,因此必须在此进行二次检查,不然式去了同步的意义。

如何选择适当的方案?

①系统是不是资源敏感型?

若是对系统资源不敏感,懒汉式式一种不错的选择!

②是否有性能上考虑?

若是没有性能上考虑,可使用懒汉式!

若是有性能考虑,应使用双重检查加锁或静态内部类!

注:静态内部类也有一些缺点,须要两个类才能实现,虽然不会建立静态内部类的对象,可是其 Class 对象仍是会被建立,并且是属于永久代的对象。

个人我的博客(后台建站,Tomcat集群,Redis分布式,nginx,适合初学者)

相关文章
相关标签/搜索