程序代码:

wKiom1g28c3i0mAHAAA8hsreEfg708.png


上面的就是典型的“饿汉模式”,就是急不可耐,一上来就初始化对象。那能不能使用的时候才实例化对象呢?也就是希望延迟加载,这就是所谓的“懒汉模式”。程序代码如下:


wKiom1g284zSNdClAAAtfuF-fiA353.png


在并发情况下,多个线程同时“抵达” if判断这块,那么势必对象会被多次new。那么“懒汉模式”下,如何保证并发呢?简单来说,我们可以在getInstance方法上直接打上synchronized即可,如下:


wKiom1g29NvSsoKUAAAfScc9r-A886.png


要知道此时锁住的是class对象,多个线程之间单个进入方法执行,确实解决了问题。但是由于锁的级别是在方法上,那么每一次获取单例,都不得不加锁,效率太低,如何改进呢?


wKiom1g29feBjGR-AAAi494EYeA238.png


把synchronized的锁范围缩小,“貌似”解决了问题,实则不然。如果多个线程同时通过if判断,那么在synchronized处一个个的通过的话,显然会被new多次。因此,我们需要double check instance:


wKioL1g29p-xrdL2AAAl6CNWyv8268.png


其实,除了上面的方式外,还有一种static inner class的方式,在保证多线程安全的情况下,更加高效、优雅:


wKiom1g2-HmAeBVOAABGSbFf7yg736.png


通过静态内部类的方式,同样可以达到使用的时候才加载,而且完全避免了并发下的问题!在实际开发中也是使用最为广泛的!