单例模式 - 图1

概念

单例模式:确保一个类只有一个实例,并提供一个全局访问点

三要素

1.私有静态属性,用于存取类的唯一实例

2.公共静态方法,用于提供对该唯一实例的存取访问,如果实例未创建,则创建该实例 (静态变量只能在静态方法中应用)。

3.用于限制类再次实例化的方式。通常使用私有构建函数的方式来实现。

代码展示

饿汉模式

  1. /**
  2. * 饿汉模式
  3. */
  4. public class SingletonHunger {
  5. private static SingletonHunger singletonHunger;
  6. static {
  7. singletonHunger = new SingletonHunger();
  8. }
  9. private SingletonHunger(){
  10. }
  11. public static SingletonHunger getSingletonHunger() {
  12. return singletonHunger;
  13. }
  14. }

懒汉模式

  1. /**
  2. * 懒汉模式
  3. */
  4. public class SingletonLazy {
  5. private static SingletonLazy singletonLazy;
  6. private SingletonLazy(){
  7. }
  8. public static SingletonLazy getSingletonLazy() {
  9. if(singletonLazy==null) {
  10. singletonLazy = new SingletonLazy();
  11. }
  12. return singletonLazy;
  13. }
  14. }

双重加锁

  1. /**
  2. * 双重加锁实现
  3. *
  4. * 另外需要注意的是双重加锁要对 instance 域加上 volatile 修饰符。
  5. * 由于 synchronized 并不是对 instance 实例进行加锁(因为现在还并没有实例),
  6. * 所以线程在执行完第11行修改 instance 的值后,应该将修改后的 instance 立即写入主存(main memory),
  7. * 而不是暂时存在寄存器或者高速缓冲区(caches)中,以保证新的值对其它线程可见。
  8. 补充:第20行可以锁住任何一个对象,要进入临界区必须获得这个对象的锁。由于并不知道其它对象的锁的用途,
  9. 所以这里最好的方式是对 Singleton.class 进行加锁。
  10. */
  11. public class DoubleCheck {
  12. private volatile static DoubleCheck doubleCheck;
  13. private DoubleCheck(){};
  14. public static DoubleCheck getDoubleCheck() {
  15. if(doubleCheck==null){
  16. synchronized (DoubleCheck.class){//类锁,拦截所有线程
  17. doubleCheck = new DoubleCheck();
  18. }
  19. }
  20. return doubleCheck;
  21. }
  22. }