设计模式之单例模式

Posted on 2017-10-09 20:31  future_liu  阅读(122)  评论(0编辑  收藏  举报

  设计模式是学习编程的必备的知识技能,在设计之初我们可以从最简单的单例模式入手。

  那么什么是单例模式呢?单例模式长什么样子呢?它有哪些规则呢,意思就是长成啥样就是一个单例模式了?

一、什么是单例模式

  单例模式顾名思义是只会生成一个实例的代码就是单例模式。

  他满足的特点是:

        a.这些类只能有一个实例

        b.这个可以自动实例化

        c.这个类对整个系统可见,即必须向整个系统提供这个实例。

二、如何实现单例模式

  单线程下实现单例模式分为两种方法:懒汉式和饿汉式

  ----利用java代码实现懒汉式:

  

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

 

就个人理解来看:懒汉式的意思是这个代码比较懒,直到你用的时候才会生成实例,而不是刚开始就已经生成。

他的运行过程是:如果是单线程的话,他运行到了singleton == null时,已经开始初始化了一个空的实例,但是没有赋值,当调用公开的方法getInstance时,就会判断该实例是否是null,如果不是null,直接返回该实例,如果是null那么就调用私有的构造方法,生成一个实例。私有的构造方法是提供仅有一个实例的基础,只允许类的内部调用,保证在单线程下只有一个实例生成。

  ----利用java代码实现饿汉式:

public class Singleton1{
    private static final Singleton1 singleton1 = new Singleton1();
    
    public static Singleton1 getInstance(){
            return singleton1;
    }
    private Singleton1(){};
}

就个人理解来看:饿汉式是这个代码比较饥饿,已经饿的不行了,必须立即吃到嘴里,所以在刚声明该实例时就已经调用构造方法生成了实例。

在单线程中的运行过程:当这个类加载后就会立即生成一个类实例,那么往后的代码中只要调用getInstance方法就会返回该类实例。final保证了该实例不会被改变。

注意:这两种方式只适用于单线程下,当多线程时就会存在问题,当两个线程锁定该类时,由于两个线程均检测到singleton实例对象为null,那么就会有创建两个实例对象,那么在多线程下该如何创建单例模式呢?

三、多线程下的单例模式

  刚才也说了刚才的代码在多线程下是不行的,所以我们需要修改代码以来适应多线程的变化。那么一般是加上锁,synchronized同步了,只是需要在public static Singleton getInstance()方法上加上一个synchronized即可。

public static Singleton getInstance(){

  if(singleton == null){

    synchronized(singleton.class){

      singleton = new Singleton();

    }

  }
  return singleton; }

 

  当两个线程在执行到synchronized锁时一个线程锁定了该代码,new 了一个实例,但是此时另一个等待中的线程也执行到了该行,那么此时就会继续执行从而再生成一个实例,但是此时这个肯定是不行的,所以还需要在加锁之后继续判断是否为空。修改后的代码为:

public static Singleton getInstance(){

  if(singleton==null){

    synchronized(singleton.class){

      if(singleton == null){

        singleton = new Singleton();

      }

    }

  }
  return singleton; }

 

这就是所谓的双重检查锁模式。

那么这些就是我总结出来的关于设计模式中的单例模式的一些浅显的东西。