设计模式-单例(Java&Kotlin)

229 阅读3分钟

单例的方式可以保持全局只有唯一一个内存实例。下面就让我们看下单例的几种写法及起优缺点把!

下面所有代码模版都分为Java和kotlin版本以供参考

一、饿汉模式

java实现 ☕️

public class SingleObject {

    private static SingleObject instance = new SingleObject();

    public static SingleObject getInstance() {
        return instance;
    }

    private SingleObject() {
    }
}

kotlin实现 🏖️

object SingleObject

kotlin中没有静态static关键字,使用object关键字替代静态类型

优点:

实现简单,方便。利用classloader机制,避免了现成的同步问题。 并且不使用synchronized,不需要加锁,执行效率会提高。

缺点:

在类加载时就会初始化,导致内存的浪费。

二、懒汉模式(线程不安全)

java实现 ☕️

public class SingleObject {

    private static SingleObject instance;

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

    private SingleObject() {
    }
}

kotlin实现 🏖️

class SingleObject private constructor() {
    companion object {
        private var instanceSingle: SingleObject? = null
            get() {
                if (field == null) {
                    field = SingleObject()
                }
                return field
            }

        fun getInstance(): SingleObject {
            return instanceSingle!!
        }
    }
}

kotlin中变量都会有伴生方法 get和set方法,内部伴生对象field是自身的引用

优点:

对象只有在第一次调用时候才初始化,不会提前初始化造成内存的浪费

缺点:

多线程访问时候,不能够保证对象的唯一性,非线程安全的

三、懒汉模式(线程安全)

java实现 ☕️

public class SingleObject {

    private static SingleObject instance;

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

    private SingleObject() {
    }
}

kotlin实现 🏖️

class SingleObject private constructor() {
    companion object {
        private var instanceSingle: SingleObject? = null
            get() {
                if (field == null) {
                    field = SingleObject()
                }
                return field
            }

        @Synchronized
        fun getInstance(): SingleObject {
            return instanceSingle!!
        }
    }
}

优点:

对象只有在第一次调用时候才初始化,不会提前初始化造成内存的浪费. 并且是线程安全的,保证了对象的唯一性

缺点:

性能不好,如果已经实例话了,之后每次仍需要加锁,导致不必要性能开销

四、Double Check Lock(DCL)模式

java实现 ☕️

public class SingleObject {
    private volatile static SingleObject instance;

    private SingleObject() {
    }

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

kotlin实现 🏖️

class SingleObject private constructor() {
    companion object {
        val instance: SingleObject by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            SingleObject()
        }
    }
}

lazy是kotlin中一个属性,用于延迟加载。当首次调用时,会返回花括号中的对象。之后再次调用就不会去初始化。model指定为SYNCHRONIZED表示的是线程安全的

优点:

只在需要使用到时初始化解决内存,并且只在未初始化的时候才加锁。获取时性能更高

缺点:

写法繁琐复杂

五、静态内部类模式

java实现 ☕️

public class SingleObject {
    private static class SingletonHolder {
        private static SingleObject instance = new SingleObject();
    }

    private SingleObject() {
        System.out.println("Singleton has loaded");
    }

    public static SingleObject getInstance() {
        return SingletonHolder.instance;
    }
}

kotlin实现 🏖️

class SingleObject private constructor() {
    companion object {
        val instance = SingleObject()
    }
}

优点:

延迟加载,线程安全

缺点:

无法传递参数

六、枚举单例模式

java实现 ☕️

public class SingleObjectJava {

    private SingleObjectJava() {

    }

    /**
     * 枚举类型是线程安全的,并且只会装载一次
     */
    private enum Singleton {
        INSTANCE;

        private final SingleObjectJava instance;

        Singleton() {
            instance = new SingleObjectJava();
        }

        private SingleObjectJava getInstance() {
            return instance;
        }
    }

    public static SingleObjectJava getInstance() {

        return Singleton.INSTANCE.getInstance();
    }
}

kotlin实现 🏖️

enum class SingleObjectJava
{
    INSTANCE
}

优点:

写法简单,线程安全,即使使用反射也能保证实例的唯一性。相比较最完美的单例实现