zoukankan      html  css  js  c++  java
  • 单例模式

    单例模式是创建型模式,结合创建型和单例这两个关键词,我们不难想出单例模式就是保证一个类只有一个实例,每次"创建"这个类的时候都是返回这同一个实例,这就涉及到了两个问题,怎么保证只有一个实例,什么时候创建这个实例,这里我们还是用java语言来说

    怎么保证只有一个实例

    把这个类的构造方法设置为private,这样就无法new获得这个对象的实例了,但是这里有个小问题,就是序列化然后反序列这个对象是不经过构造函数的,可能会无法保证只有一个实例,为了解决这个问题我们可以为类加上如下函数

      private Object readResolve() {
        return  singleton;  //返回这个单实例
      }
    

    这样就能保证反序列化之后得到的实例也是同一个。

    我们也可以使用枚举类来实现单例模式,枚举类天然支持保证单实例的反序列化,不过使用枚举类有些不易理解。

    public enum Single {
        // 唯一枚举:
    	INSTANCE;
    
    	private String name = "single";
    
    	public String getName() {
    		return this.name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    }
    

    什么时候创建这个实例

    我们可以在类加载的时候就创建这个实例

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

    静态变量是在类加载的时候初始化这个实例的,这时候就有人会说,加载时就创建,一旦之后我们没有用到,那多浪费空间啊,还是用到的时候在加载比较好,这就是懒加载,

    public class Singleton {
        private static final Singleton instance = null;
    
        public static Singleton getInstance() {
            if (INSTANCE == null) {
                INSTANCE = new Singleton();
            }
            return INSTANCE;
        }
        private Singleton() {
        }
    }
    

    单线程貌似没什么问题,要是多个线程并发的情况下可能就会创建多个实例,接下来应该想到的就是对方法加锁解决这个问题,但是加锁影响并发性能,接着就是双重检查性能会稍微好一些[代码来自廖大的博客,懒得写了复制一下]

    public static Singleton getInstance() {  
        if (INSTANCE == null) {
            synchronized (Singleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
    

    总结

    单例模式就是实例唯一,但是我们不一定需要强制的编写代码让他唯一,也可以用约定的方式,比如Spring容器,我们把bean注册在容器里,我们要用的时候再去取,我们先不考虑Spring 容器是怎么处理的,从我们注册bean到取出使用这个实例的流程就是单例。

  • 相关阅读:
    PAT (Advanced Level) 1010. Radix (25)
    PAT (Advanced Level) 1009. Product of Polynomials (25)
    PAT (Advanced Level) 1008. Elevator (20)
    PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
    PAT (Advanced Level) 1006. Sign In and Sign Out (25)
    PAT (Advanced Level) 1005. Spell It Right (20)
    PAT (Advanced Level) 1004. Counting Leaves (30)
    PAT (Advanced Level) 1001. A+B Format (20)
    PAT (Advanced Level) 1002. A+B for Polynomials (25)
    PAT (Advanced Level) 1003. Emergency (25)
  • 原文地址:https://www.cnblogs.com/ljsh/p/12728220.html
Copyright © 2011-2022 走看看