为何说单例模式性价比高?
在面试过程当中常常让手撸的一种设计模式,而且被面的频率很是高。重点是这种设计模式很简单!java
个人我的博客(后台建站,Tomcat集群,Redis分布式,nginx,适合初学者)nginx
为何要用单例模式?面试
在开发过程当中,根据需求的不一样,有时可能要求对象实例只能有一个,这时就要使用到了单例模式。设计模式
如:Spring中的bean默认使用的都是单例模式。安全
什么是单例模式?cookie
确保对象只有一个,并提供一个全局访问点。分布式
经典的实现方式:性能
饿汉式线程
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; } }
饿汉式: 在类加载时就建立对象,不管是否使用都会建立,天生线程安全。
懒汉式:延迟化实例,在使用时才会建立,线程不安全,相比饿汉式来讲对于资源敏感的对象很重要,能节省系统资源。
双重校验:延迟化实例,线程安全,可是牺牲性能来提高安全。
静态内部类:只有在,内部类在第一次调用Holder.uniqueInstance时才会建立实例,因此也是一种延迟化实例的机制,经过静态内部类只有第一次引用才会被加载,因此是线程安全的;而且经过反射,也没法从外部类获取内部类的属性。因此这种形式,很好的避免了反射入侵。
为何进行双重校验?
因为同步范围比较精确,也可能出现安全问题,即在判断为null和加锁之间另外一个线程已经建立了对象,由于使用了volitile关键字保证了对象的可见性,因此必须在此进行二次检查,不然式去了同步的意义。
如何选择适当的方案?
①系统是不是资源敏感型?
若是对系统资源不敏感,懒汉式式一种不错的选择!
②是否有性能上考虑?
若是没有性能上考虑,可使用懒汉式!
若是有性能考虑,应使用双重检查加锁或静态内部类!
注:静态内部类也有一些缺点,须要两个类才能实现,虽然不会建立静态内部类的对象,可是其 Class 对象仍是会被建立,并且是属于永久代的对象。