Java进阶之单例模式

Java进阶之单例模式

  • Java进阶之单例模式

单例模式 singleton

  • 永远都是一个对象

懒汉式

  • 在多线程下是非线程安全
  • 单例模式的懒汉式体现了缓存的思想,延时加载就是一开始不要加载资源或者数据,一直 等,等到马上就要使用这个资源的或者数据时才去加载。
  • 懒汉式是定性的时间换空间,不加同步的懒汉式是线程不安全的
public class Singleton1 {

    private static Singleton1 singleton = null;
    private Singleton1(){
    }
    public static Singleton1 getInstance(){
        //判断内存中是否对singleton对象实例化,如果有,就给予当前实例化,如果没有,则new一个
        synchronized (Singleton1.class){
            if(singleton == null){
                singleton = new Singleton1();
            }
        }

        return singleton;
    }
    //两个类,放一起了,我懒
     public static void main(String[] args) {
        Singleton1 s1 = Singleton1.getInstance();
        Singleton1 s2 = Singleton1.getInstance();
        System.out.println(s1 == s2);
    }
}

饿汉式

  • 饿汉式是典型的空间换时间,当类装载的时候就会创建类实例,不管用不用,先创建出来,然后每次调用的时候,就不需要判断了,节省了运行时间。
  • 饿汉式在多线程模式下默认是线程安全的
  • 将对象使用final,防止对象被改变
  • 可以将整个方法加锁,防止线程不安全
public class Singleton2 {
    private static final Singleton2 singleton2 = new Singleton2();
    private Singleton2(){

    }
    public synchronized static Singleton2 singleton2(){
        return singleton2;
    }
    //两个类,放一起了,我懒
    public static void main(String[] args) {
        Singleton2 s3 = Singleton2.singleton2();
        Singleton2 s4 = Singleton2.singleton2();
        System.out.println(s3 ==s4);
    }
}

使用静态内部类实现单例模式

  • 当getInstance方法第一次被调用,第一次读取SingletonHolder.instance,导致SingletonHolder类初始化
  • 类在装载并被初始化的时候,会初始化它的静态域,从而创建Singleton的实例
  • 由于是静态的域,因此只会在虚拟机装载类的时候初始化一次,并由虚拟机来保证它的线程安全性
public class Singleton {
    private static class SingletonHoler {
        /**
         * 静态初始化器,由JVM来保证线程安全
         */
        private static Singleton instance = new Singleton();
    }
 
    private Singleton() {
    }
 
    public static Singleton getInstance() {
        return SingletonHoler.instance;
    }
    public static void main(String[] args) {
        Singleton s3 = Singleton.singleton2();
        Singleton s4 = Singleton.singleton2();
        System.out.println(s3 ==s4);
    }
}

使用枚举来实现单例

  • 枚举实现单例是最为推荐的一种方法,因为它更简洁并且就算通过序列化,反射等也没办法破坏单例性
  • Java枚举类型的基本思想:通过公有的静态final域为每个枚举常量导出实例的类
  • 从某个角度讲,枚举是单例的泛型化,本质上是单元素的枚举
public enum EnumSingle {

    INSTANCE;

    public EnumSingle getInstance() {
        return INSTANCE;
    }
}
如有问题,请发送邮件至buxiaqingcheng@163.com或者buxiaqingcheng@dingtalk.com
原文地址:https://www.cnblogs.com/zhenzhunaichabujiatang/p/13514897.html