单例的方式可以保持全局只有唯一一个内存实例。下面就让我们看下单例的几种写法及起优缺点把!
下面所有代码模版都分为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
}
优点:
写法简单,线程安全,即使使用反射也能保证实例的唯一性。相比较最完美的单例实现