java单例模式几种实现方式分析

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了java单例模式几种实现方式分析脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

饿汉模式

线程安全,调用效率高,但是不能延时加载

public class ImageLoader{       PRivate static ImageLoader instance = new ImageLoader;       private ImageLoader(){}       public static ImageLoader getInstance(){             return instance;         }  }

这样做的好处是编写简单,但是无法做到延迟创建对象。但是我们很多时候都希望对象可以尽可能地延迟加载,从而减小负载,所以就需要下面的懒汉法:

懒汉模式

单线程写法
public class Singleton {     private static Singleton singleton = null;     private Singleton(){}     public static Singleton getSingleton() {         if(singleton == null) singleton = new Singleton();         return singleton;     } }

这种方法可以实现延时加载,但是有一个致命弱点:线程不安全(可见性,有序性)。如果有两条线程同时调用getSingleton()方法,就有很大可能导致重复创建对象。

考虑线程安全的写法

public class Singleton {     private static volatile Singleton singleton = null;       private Singleton(){}       public static Singleton getSingleton(){         synchronized (Singleton.class){             if(singleton == null){                 singleton = new Singleton();             }         }         return singleton;     }     }

这种写法考虑了线程安全,将对singleton的null判断以及new的部分使用synchronized进行加锁。同时,对singleton对象使用volatile关键字进行限制,保证其对所有线程的可见性,并且禁止对其进行指令重排序优化。如此即可从语义上保证这种单例模式写法是线程安全的。注意,这里说的是语义上,实际使用中还是存在小坑的,会在后文写到。

public class Singleton {     private static volatile Singleton singleton = null;       private Singleton(){}       public static Singleton getSingleton(){         if(singleton == null){             synchronized (Singleton.class){                 if(singleton == null){                     singleton = new Singleton();                 }             }         }         return singleton;     }     }

这种写法被称为“双重检查锁”,顾名思义,就是在getSingleton()方法中,进行两次null检查。看似多此一举,但实际上却极大提升了并发度,进而提升了性能。为什么可以提高并发度呢?
在单例中new的情况非常少,绝大多数都是可以并行的读操作。因此在加锁前多进行一次null检查就可以减少绝大多数的加锁操作,执行效率提高的目的也就达到了。

脚本宝典总结

以上是脚本宝典为你收集整理的java单例模式几种实现方式分析全部内容,希望文章能够帮你解决java单例模式几种实现方式分析所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。