经典指数          
原因
567
浏览数
0
收藏数
 

用至少两种方式实现一个Singleton(单例模式)。

     举报   纠错  
 
切换
1 个答案
这里以两种解决DCL(双重检查锁)失效问题的方式来创建 1.利用volatile关键字解决DCL失效问题public class VolatileSolveDCLSingleTon {// volatile解决了处理器乱序执行的问题从而解决了DCL失效问题private volatile static VolatileSolveDCLSingleTon instance;private VolatileSolveDCLSingleTon(){} public static VolatileSolveDCLSingleTon getInstance(){ // 为空时才去获取对象锁 if(instance == null){ synchronized (VolatileSolveDCLSingleTon.class){ // 此时仍为空才执行new操作,避免多个线程突破了第一层检查 if(instance == null){ instance = new VolatileSolveDCLSingleTon(); } } } return instance; }} 2.使用静态内部类方式解决DCL失效问题public class StaticSolveDCLSingleTon { // 静态内部类方式解决DCL失效问题private static class SingleTonHolder{ private static final StaticSolveDCLSingleTon instance = new StaticSolveDCLSingleTon(); }private StaticSolveDCLSingleTon(){} public static final StaticSolveDCLSingleTon getInstnce(){ return SingleTonHolder.instance; }} 3.可能有人想问什么是DCL失效问题,这里简单讲下: DCL失效:我们看instance = new SingleTon();这一句,在JDK1.5以前,处理器为了保证执行效率,会在保证程序执行结果不变的情况下进行指令的乱序执行,这一句处理器的执行过程分三步: 1.在堆中为SingleTon对象开辟一块存储空间2.调用new SingleTon()来执行类的初始化3.执行"="过程,即将instance引用指向SingleTon对象在堆中的内存空间 乱序执行发生在上面2、3的过程,也就是3可能会先于2执行,一般情况下这样是不影响程序的结果的,最终都是instance指向了对象在堆中的内存空间.但是在DCL中,我们进行了两次instance判空,当第一次判空失败时我们会直接返回instance对象,问题就出在这里,当我们一个线程在执行上面new过程并且3先于2执行了的时候,假如有另一个线程也调用了getInstance方法,这时会进行第一次判空,由于3过程("="操作)执行后此时 instance != null,所以另一个线程会直接被返回instance,但是此时instance是未创建完全的,是不完整的,所以使用的时候就会出错,这就是DCL失效问题 纯手打,有错望指教
 
切换
撰写答案
扫描后移动端查看本题