首页 > 其他 > 详细

单例模式

时间:2021-02-19 23:40:59      阅读:34      评论:0      收藏:0      [点我收藏+]

单例模式就是采用一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。
JDK中,java.lang.Runtime就是经典的单例模式(饿汉式)。

饿汉式(静态常量)

  1. 构造器私有化(防止被new)
  2. 类的内部创建对象
  3. 向外暴露一个静态的公共方法(getInstance)
public class SingletonTest01 {
    // 私有化SingletonTest01使其无法被new
    private SingletonTest01() {
    }

    private final static SingletonTest01 instance = new SingletonTest01();

    public static SingletonTest01 getInstance(){
        return instance;
    }
}

方式可用但可能造成内存浪费

饿汉式(静态代码块)

public class SingletonTest02 {
    private SingletonTest02() {
    }

    private static SingletonTest02 instance;

    static {
        instance = new SingletonTest02();
    }

    public static SingletonTest02 getInstance(){
        return instance;
    }
}

也可能造成内存浪费

懒汉式(线程不安全)

public class SingletonTest03 {
    private SingletonTest03() {
    }

    private static SingletonTest03 instance;
    // 用到该方法时 才去创建
    public static SingletonTest03 getInstance(){
        if(instance == null){
            instance = new SingletonTest03();
        }
        return instance;
    }
}

如果在多线程下,多个线程同时进入这个判断语句就会产生多个实例,所以多线程环境下不可使用这种方式

懒汉式(线程安全)

public class SingletonTest04 {
    private SingletonTest04() {
    }

    private static SingletonTest04 instance;
    // 用到该方法时 才去创建
    public static synchronized SingletonTest04 getInstance(){
        if(instance == null){
            instance = new SingletonTest04();
        }
        return instance;
    }
}

解决了线程安全问题,但是效率太低了,每个线程想获得实例时,执行getInstance()方法时都要进行同步
实际开发中不推荐

懒汉式(线程安全,同步代码块)

本意是想对第四种同步方法进行优化,但还是可以有多条线程进入if判断语句,所以线程并不安全
不能使用

双重检查(DoubleCheck)

public class SingletonTest05 {
    private SingletonTest05() {
    }

    private static volatile SingletonTest05 instance;

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

好处就在于进行了两次if(singleton == null)检查,保证线程安全,实例化代码只用执行一次,后面再次访问时外层if判断避免了反复的方法同步
线程安全;延迟加载;效率高;在实际开发中推荐使用这种单例模式

静态内部类

public class SingletonTest06 {
    private SingletonTest06() {
    }

    private static class SingletonInstance{
        private static final SingletonTest06 INSTANCE = new SingletonTest06();
    }

    public static synchronized SingletonTest06 getInstance(){
        return SingletonInstance.INSTANCE;
    }
}

采用了类装载的机制来保护初始化实例时只有一个线程,静态内部类在类装载的时候不会实例化,而是在需要实例化的时,调用getInstance方法,才会装载SingletonInstance类,类的静态属性指挥在第一次加载时初始化,所以JVM帮我们保证了线程的安全性,类初始化时,别的线程时无法进入的。
避免了线程不安全,利用静态内部类特点实现延迟加载,效率高推荐使用

枚举方式

public enum  SingletonTest07 {
    INSTANCE;// 属性
    public void sayOK(){
        System.out.println("ok");
    }
}

单例模式注意事项

  1. 单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些频繁创建销毁的对象,使用单例模式可以提高性能
  2. 当想实例化一个单例类时,必须记住使用相应的获取对象的方法
  3. 单例模式使用场景:被常用到的需要频繁进行创建和销毁的对象、重量级对象(比如数据源、session工厂等)

单例模式

原文:https://www.cnblogs.com/wdaa/p/14417455.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!