java单例模式的实现方式

单例模式是比较简单的设计模式,但在工作中发现能正确规范书写的不多。下面列举一下Java中常见的实现方式。注意构造函数需要私有化。

1. 非懒加载模式。

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

2. 懒加载模式。

   A. 同步getInstance方法

public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public synchronized static Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
   B. 双重检查加锁

主要是避免每次getInstance都要加锁。也是实现最复杂的一个。注意instance必须设为volatile。因为通过两次对instance的判空来决定初始化,不使用volatile来保证线程读取的对象确实与内存中保存一致,会导致未初始化完成的对象被发布和被引用。

public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if(instance == null) {
            synchronized (Singleton.class) {
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
  C. 延迟初始化占位类模式(我称为静态内部类)

通过静态内部类持有Instance,通过jvm分配静态内存时的同步机制,可以确保对象延迟初始化,并正确发布。

public class Singleton {
    private Singleton() {}
    private static final class Holder {
        public static final  Singleton instance = new Singleton();
    }
    public static Singleton getInstance() {
       return Holder.instance;
    }
}
  D. 借用内联

通过声明一个内联元素,确保instance的唯一性。我认为完全没必要。为了实现单例,而改变对象的属性(class改为enum),代码可读性很差,只是借用下技巧而已。

public enum Singleton {
    INSTANCE;
    private Singleton() {}
    public void work() {
        //to do        
    }
}
综上所述,C是实现懒加载的最简单明了方式,项目中可以常用。不必考虑到反射来破坏单例,这个感觉已经走远了。还有甚者,在 延迟初始化占位类模式实现内部类的时候通过enum来替代,说确保enum构造函数只执行一次。我只能说,呵呵了。要做的话,用底层的UnSafe和Classloader什么不好做,可读性往往大于奇淫巧技。
双重检查加锁一般已经废弃,如果需要进一步了解,可以参考《Java Concurrency in practice》一书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值