首页 > 其他 > 详细

设计模式之单例模式

时间:2020-12-16 19:03:26      阅读:40      评论:0      收藏:0      [点我收藏+]

设计模式之单例模式

单例模式就是在堆中只存在一份实例,这样的好处就是可以节省内存,但是也可可能引发多线程问题,所以在单例中最好把不要设置可供外界访问的成员变量。

Java中实现单例模式一共有七种,首先都需要将静态方法私有化,具体如下

1.饿汉式 静态常量

将构造方法私有化后使用静态常量进行初始化,对外提供一个静态方法返回。

public class Singleton {

    private Singleton() {

    }

    private static final Singleton SINGLETON = new Singleton();

    public static Singleton getSingleton() {
        return SINGLETON;
    }
}

2饿汉式 静态代码块

根据静态代码块在类初始化时只会加载一次,而且JVM保证了类加载时是线程安全的。所以此方式效率也很高,但是有个缺陷就是无论使用与否都会在内存中存在一份实例,若不使用到的时候会造成内存浪费一点

public class Singleton2 {
    private Singleton2() {

    }
    private static Singleton2 SINGLETON2;
    static {
        /**
         * 静态代码块会在类加载时执行 在构造函数之前
         */
        SINGLETON2 = new Singleton2();
    }

    public static Singleton2 getSingleton2() {
        return SINGLETON2;
    }
}

3.懒汉式(线程不安全)

此方式线程不安全,因为在创建实例时,当多个线程都成功进入到创建实例过程中后,就会创建多个对象。

public class Singleton3 {
    private Singleton3() {

    }

    private static Singleton3 instance = null;

    public static Singleton3 getInstance() {
        if (instance == null) {
            instance = new Singleton3();
        }
        return instance;
    }
}

4.懒汉式(效率低的线程安全)

根据3改正,因为可能存在多个线程同时进入,所以直接加个synchronized来保证线程安全,但是锁的粒度较大,当有很多线程过来时即使已经创建过实例也要进行同步,等待去获得锁对象

public class Singleton4 {
    private Singleton4() {
    }
    private static Singleton4 instance = null;

    public static synchronized Singleton4 getInstance() {
        if (instance == null) {
            instance = new Singleton4();
        }
        return instance;
    }
}

5.双重检查法

根据4改编,既然锁方法的粒度太大那么就锁销粒度,使用同步代码块的方式进行,如果对象没有创建就使用同步代码块去创建,Spring中的实现也是类似。这样的当对象实例创建完成后则不会进入同步代码块

public class Singleton5 {
    private Singleton5() {

    }
    private static Singleton5 instance = null;

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

6.静态内部类

根据静态加载时才会被初始化的特性,再根据类加载时是线程安全的

public class Singleton6 {
    private Singleton6() {

    }
    private static class Instance {
        /**
         * 静态内部类只有在使用时会被初始化一次
         *
         */
        private static final Singleton6 instance = new Singleton6();
    }

    public static Singleton6 getInstance() {
        //调用静态内部类的静态常量
        return Instance.instance;
    }
}

7.枚举

枚举类型天然单例 是实现单例模式的最佳实践,因为序列化反序列化后也是单例模式

enum Singleton8 {
    /**
     * 实例对象
     */
    INSTANCE;

    public void sayok() {
        System.out.println("ok");
    }
}

设计模式之单例模式

原文:https://www.cnblogs.com/clion/p/14143978.html

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