首页 黑客接单正文

不使用synchronized和lock,如何实现一个线程安全的单例?

不使用synchronized和lock,如何实现线程安全的单例?

静态内部的是静态内部类和枚举。很好,这两种 *** 确实可以实现。

枚举

  • publicenumSingleton{
  • INSTANCE;
  • publicvoidwhateverMethod(){
  • }
  • }
  • 静态内部类

  • publicclassSingleton{
  • privatestaticclassSingletonHolder{
  • privatestaticfinalSingletonINSTANCE=newSingleton();
  • }
  • privateSingleton(){}
  • publicstaticfinalSingletongetInstance(){
  • returnSingletonHolder.INSTANCE;
  • }
  • }
  • 还有人回答很简单:饿汉。很好,这也是对的。

    饿汉

  • publicclassSingleton{
  • privatestaticSingletoninstance=newSingleton();
  • privateSingleton(){}
  • publicstaticSingletongetInstance(){
  • returninstance;
  • }
  • }
  • 饿汉变种

  • publicclassSingleton{
  • privatestaticclassSingletonHolder{
  • privatestaticfinalSingletonINSTANCE=newSingleton();
  • }
  • privateSingleton(){}
  • publicstaticfinalSingletongetInstance(){
  • returnSingletonHolder.INSTANCE;
  • }
  • }
  • (更多单例实现 *** 见:单例模式的七种写法)

    问:实现单例的真正原则是什么?

    答:以上实现 *** 都是借助的。ClassLoader线程安全机制。

    先解释一下为什么都是借助了ClassLoader。

    先说两个饿汉,其实都是通过定义静态成员变量来保证的。instance当类别初始化时,可以实例化。那为什么要让它变成呢?instance实例化可以保证类初始化时的线程安全吗?因为类的初始化是由ClassLoader完成,这其实是用的ClassLoader线程安全机制。

    除了静态内部类,这种方式和两种饿汉方式只有细微的区别,但做法有点优雅。这种 *** 是Singleton类被装载,instance不一定是初始化的。SingletonHolder类别没有主动使用,只有通过调用显示getInstance装载只有在 *** 中才会显示SingletonHolder类,从而实例化instance。。。但原则和饿汉一样。

    ***说到枚举,其实如果把枚举类反序列化,你会发现他也用过static final修改每个枚举项(详见:深入分析Java的枚举类型—-枚举的线程安全序列化问题)

    到目前为止,我们已经说清楚了,所有看官的回答都被利用了。ClassLoader线程安全机制。至于为什么ClassLoader线程安全,这里可以直接回答:ClassLoader的loadClass该 *** 用于加载类synchronized关键词。正因为如此, 在整个装载过程中默认同步(线程安全),除非被重写。(详见:深入分析Java的ClassLoader机制(源码级)

    哈哈哈哈!!!~所以,这里可以说,每个人的答案只有正确的一半。虽然没有显示使用情况synchronized和lock,但还是间接用!

    所以这里再问一句:不用synchronized和lock,如何实现线程安全的单例?

    【本文是51CTO专栏作者Hollis原创文章,作者微信公众号Hollis(ID:hollischuang)】

    戳这里,看作者更好的文章

       
    版权声明

    本文仅代表作者观点,不代表本站立场。
    本文系作者授权发表,未经许可,不得转载。