1. 什么是单例模式?

    单例模式:就是在我们的应用程序中某个类值存在一个实例。

    1. 懒汉式:要用的时候才进行实例化(懒人有拖延症)

        1. 私有化构造方法;

        2. 声明一个私有化静态的当前对象变量,不进行实例化;

        3. 提供加同步锁的公开的静态方法,用于获取当前对象,当对象为null时创建,不为null时直接返回;

    缺点:在并发的情况下,多个线程访问这个对象时候,因为他是同步的,需要等待,影响性能;

public class Student {
private Student(){}
            private static Student student = null;    
            public static synchronized Student getInstance(){
                    if(student == null){
                       student = new Student();
                    }
                    return student;
               }
          }

    2. 饿汉式:

        1. 私有化构造方法

        2. 声明一个私有化静态的当前对象,需要进行实例化

        3. 提供公开的静态方法,用于获取当前对象,

    缺点:一次性创建好了,无法往单例对象的构造方法传参,不能起到延迟加载的效果,而且占据内存;

   

public class Student {
                 private Student(){}
                private static Student student = new Student();
                public static  Student getInstance(){
                    return student;
                }
        }



    3. 双重判断:推荐使用

   

volatile private static entity = null;
        public static entity getInstance(){
        if(entity == null){
             synchronized(entity.class){
                 if(entity == null){
                     entity = new entity();
                 }
             }
        }
        return entity;
    }

    synchronized(entity.class) 在这个类上加入同步锁,这个类中当前方法都不能被其他线程调用;

    volatile:当多个线程访问同一个变量是,如果其中一个线程改变了这个变量的值,

    其他线程能被及时通知到这个变量已经发生 改    变了;

    他会屏蔽掉虚拟机的一些代码优化,一般不适用;

    4. enum:枚举

        枚举的构造方法默认是私有的

        通过枚举实现单例模式;简洁,自由序列化,又不存在多线程的问题;一般在java源码中见到此用法;

     

public enum  EnumStudent {
红色"),white(2,"白色");
            private int key;
            private String value;
            EnumStudent(int key,String value){
                this.key = key;
                this.value = value;
            }
            public int getKey() {
                return key;
            }
            public String getValue() {
                return value;
            }
    }

    5. 静态内部类实现单例模式:

        既能够做到延时加载,又能够实现线程安全;

        静态属性,静态代码块在类加载的时候就分配空间了,而静态类在调用的时候才去加载;

      

public class Singleton{
             private Singleton(){}
             private static class SingletonHolder{
              //静态内部类的静态属性的实例化,由JVM保证线程的安全
              private static Singleton instance = new Singleton();
             }
             public static Singleton getInstance(){
只有调用getInstance方法时,才回去实例化instance属性
                  return SingletonHolder.instance;
             }
        }