优秀的设计结构能够规避不少潜在的性能问题,对系统性能的影响可能远远大于代码的优化,因此咱们须要知道一些设计模式和方法。设计模式
单例模式:多线程
单例模式是一种对象建立模式,用于生产一个对象的实例,它能够确保系统中一个类只产生一个实例,这样作有两个好处:函数
1.对于频繁使用的对象,能够省略建立对象所花费的时间,这对于那些重量级对象而言,是很是可观的一笔系统开销。性能
2.因为new操做的次数减小,因此系统内存的使用评率也会下降,这将减小GC压力,缩短GC停顿时间。优化
因为以上两点可知单例模式的使用对于系统的关键组件和频繁使用的对象来讲是能够有效的改善系统的性能的。线程
单例的核心是经过一个方法返回惟一的一个对象实例,首先单例类必须有一个private访问级别的构造函数,由于,只有这样,才能保证单例不会再系统中的其余代码内被实例化,其次,instance成员变量和getInstance方法必须是static的。设计
须要对instance实例作延迟加载对象
假如单例的建立过程很慢(构造方法中有其余耗时操做),而且不是延迟加载的(因为instance成员变量是static定义的,所以在JVM加载单例类时,单例对象就会被建立),若是此时这个单例类还在系统中扮演着其余角色(单例类还有其余非建立单例的静态方法),那么在任何使用这个单例类的地方都会初始化这个单例变量,而无论是否会被用到。也就是说虽然并无使用单例类,可是它仍是被建立出来了,这是咱们不肯意看到的,为了解决这个问题,就须要引入延迟加载机制。内存
对于静态变量instance初始值赋null,确保系统启动时没有额外的负载,在getInstance()工厂方法中,判断当前单例是否已存在,若存在则返回,若不存在则建立单例,同时getInstance()方法应该是同步的。get
为了延迟加载而引入同步关键字会下降系统性能,为了解决这个问题,可使用内部类来维护单例的实例,当单例类被加载时,其内部类并不会被初始化,因此能够确保单例类被加载进入JVM时,不会初始化单例类,而当getInstance方法被调用时才会加载SingletonHolder从而初始化instance,因为实例的创建是在类加载时完成,故天生对多线程友好,getInstance方法也不须要使用同步关键字,因此这种方法兼容上边说的两种实现的优势。
一般状况下,以上方式实现的单例已经能够确保在系统中中存在惟一的实例了,可是也有例外的状况致使系统生成多个实例,好比,在代码中经过反射机制强行调用单例类的私有构造函数来生成多个单例。针对这种极端的状况也有克服的办法,具体办法请参考笔者头条号中讲解单例模式的其余两篇文章。