s

song0313

V1

2022/12/06阅读:12主题:红绯

设计模式之-单例模式

/**
 * Created by szw on 2021/5/14.
 * 懒汉式单例,线程不安全
 * 是否 Lazy 初始化:是
 * 是否多线程安全:否
 * 实现难度:易
 * 描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
 * 这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
 * @author song
 */

public class Single01 {
    //先声明一个本类实例对象作为自己的成员变量
    private static Single01 instance;
    //一个私有的构造方法
    private Single01(){

    }
    //提供一个public静态方法获取实例,因为懒所以调用此方法时才初始化实例
    public static Single01 getInstance(){
        //如果没有实例则new一个并赋值给成员变量instance,有的话直接返回
        if (instance == null){
            instance = new Single01();
        }
//      返回instance
        return instance;
    }
}
/**
 * Created by szw on 2021/5/14.
 *懒汉式单例,线程安全方式
 * 是否 Lazy 初始化:是
 * 是否多线程安全:是
 * 实现难度:易
 * 描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
 * 优点:第一次调用才初始化,避免内存浪费。
 * 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
 * getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。
 * @author szw
 */

public class Single02 {
    private static Single02 instance;
    private Single02(){ }
    //加锁保证多线程安全
    public static synchronized Single02 getInstance(){
        if (instance == null){
            return new Single02();
        }
        return instance;
    }
}
/**
 * Created by szw on 2021/5/14.
 *饿汉式单例
 * @author szw
 */

public class Single03 {
    //因为饿汉比较饿,所以上来就初始化实例
    private static Single03 instance = new Single03();

    //私有构造方法
    private Single03() {
    }

    //提供一个public静态方法访问此实例
    public static Single03 getInstance() {
        //因为开始就初始化实例了,所以直接返回此实例
        return instance;
    }

    public static void main(String[] args) {
        Single02 single02 = Single02.getInstance();
        System.out.println(single02);
    }
}
/**
 * Created by szw on 2021/5/14.
 *双重检查锁单例
 * JDK 版本:JDK1.5 起
 * 是否 Lazy 初始化:是
 * 是否多线程安全:是
 * 实现难度:较复杂
 * 描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
 * getInstance() 的性能对应用程序很关键。
 * @author szw
 */

public class Single04 {
    //加volatile 是因为非原子操作
    private volatile static Single04 instance;
    private Single04(){ }

    public static Single04 getInstance(){
        //第一次判空是如果为空,创建实例,否则说明已有实例,直接返回实例
        if (instance == null){
            synchronized (Single04.class){
                //为什么再进行一次判空,因为可能有别的线程已经判断完第一次判空,等待得到锁的线程执行结束,
                // 此线程会继续执行,所以这时要再判断一次,不然此线程会再创建一个实例
                //但是这种写法是绝对安全的吗?可以通过反射破坏吗?
                if (instance == null){
                    instance  =  new Single04();
                }
            }
        }
        return instance;
    }
}
/**
 * Created by szw on 2021/5/14.
 *静态内部类实现单例
 * @author szw
 */

public class Single05 {
    private static class SingletonHolder {
        private static final Single05 INSTANCE = new Single05();
    }
    private Single05 (){}
    public static final Single05 getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public static void main(String[] args) {
        System.out.println(Single05.getInstance());
        System.out.println(Single05.getInstance());
        System.out.println(Single05.getInstance());
    }
}

执行结果:

分类:

后端

标签:

Java

作者介绍

s
song0313
V1