单例模式
单例模式,也叫单一实例,其实就是为了保证一个类有且只有一个实例,并且为客户端其他访问提供一个全局的访问点而设计的一种模式。单例模式有多种实现实现方式,一般常见的有饿汉式单例、懒汉式单例,然后其它方式基本都是针对这些单例模式进行优化。
所谓单例,就是要控制只有一个实例,要只有一个实例,首先就要控制创建实例的地方,也就是说不能任何地方可以创建实例;举个例子,创建单例类,那么我们就可以将这个类的构造方法private,只有自己才能创建,然后再提供一个统一的创建实例入口就可以了,单例的基本原理就是这样了。来,上代码:
一、懒汉模式
懒汉模式所谓懒汉,懒其实就是只有去对象时才创建对象,创建完之后,就存在全局变量,后面再来取的就可以取值了。
二、饿汉模式
饿汉模式饿汉式,其实就是跟懒汉相反,在类加载时就已经创建了实体了,每次调用访问接口,直接取值就可以了。
以上方式就以最简单、最常见实现了单例模式。但是,还没完美,怎么说呢?懒汉式创建,如果在多线程里面,就极易产生问题,多个线程,同时判判为空,进入创建对象,那么这个对象变成了多线程里后创建的对象。那么如何优化?可以在懒汉模式的方法中加一个synchronized锁,如
方法加锁这样也就保证了多线程情况下,对象唯一。哪么问题来了,唯一保证了,但是高并发多线程情况下,读取方法时都加锁,加大程度下降低了效率。因此,加下还可以优化:双重检查锁;如
双重检查这样既可以保证了单例,延迟了加载对象,也提高了效率。这样是不是很完美了?不。这不是最理想的单例模式。synchronized通常称为重量级锁,而volatile是Java提供的一种轻量级的同步机制,简称轻量级锁。一定程度上会屏蔽虚拟机对代码的优化,降低了虚拟机的执行效率,因此如何优化呢?这里引入一个内部类实例生成方法。来上代码:
内部类实例当第一次访问内部类时 ,虚拟机控制了内部类静态方法实例的生成,保证了实例的唯一,既可以不加锁,也可以延长加载实例,这才是完美做法。