Kotlin单例几种方式

版主
2025-07-08
点 赞
0
热 度
1
评 论
0

文章摘要

AI摘要GPT

1、饿汉式

 object StaticA {
     val x = 123
 } 

等价于java中的:

 public class StaticA  {
   public static final StaticA  sInstance = new StaticA()
   private StaticA () {
   }
 } 

优点:

  • 实现简单

  • 线程安全,因为其在类加载时就进行了初始化,虚拟机内部保证其线程安全,保证对常量/静态变量只进行一次初始化

缺点:

  • 在类加载时就创建了静态对象,实际上可能不会用到,所以对资源来说是浪费了,同时时类的初始化变慢,性能上并不是很好

2、懒汉式

懒汉式就是懒加载,在使用时在进行初始化,其实现如下:

 class SingleA {
     companion object {
         val sInstance by lazy(LazyThreadSafetyMode.NONE) {
             SingleA()
         }
     }
 } 

等价于java的:

 public class SingleA  {
     private static sInstance;
     
     private SingleA() {
     }
     
     public static SingleA getInstance() {
         if (sInstance == null) {
             sInstance  = new SingleA()
         }
         return sInstance;
     }
 } 

优点:

  • 延迟到使用时才进行初始化,提高了类加载的性能

缺点:

  • 非线程安全,多个线程同时访问情况下,会创建多个实例

3、懒汉同步方法式

此方法是在第2中方式上在给房间加锁来实现,如下:

 class SingleB {
     companion object {
         var sInstance: SingleB? = null
 ​
         @Synchronized
         fun getInstance(): SingleB? {
             if (sInstance == null) {
                 sInstance = SingleB()
             }
             return sInstance
         }
     }
 } 

等价于java的:

 public class SingleB {
     private static SingleB sInstance;
   
     private SingleB() {
     }
     
     public static synchronized SingleB getInstance() {
         if (sInstance == null) {
             sInstance = new SingleB();
         }
         return sInstance;
     }
 } 

优点:

  • 延迟到使用时才进行初始化,提高了类加载的性能

  • 对方法使用了同步锁synchronized,保证了线程安全

缺点:

  • synchronized应用在方法上,所有是对整个方法加了锁,所以性能上稍差

4、懒汉同步块式(推荐)

与第3中的方式差不多,不同的是同步锁应用在方法的内部语句块中:

 class SingleC {
     companion object {
         val sIntance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
             SingleC()
         }
     }
 } 

等价于java的:

 public class SingleC {
     private static SingleC sIntance;
     private SingleC() {
     }
     public static SingleC getInstance() {
         if (sIntance == null) {
             synchronized (SingleC.class) {
                 if (sIntance == null) {
                     sIntance = new SingleC();
                 }
             }
         }
         return sIntance;
     }
 } 

优点:

  • 延迟到使用时才进行初始化,提高了类加载的性能

  • 在创建对象的语句块中使用了同步锁synchronized,保证线程安全的同时,降低了锁的作用范围

缺点:

  • 需要1-2次的空判断

5、静态内部类式(推荐)

静态内部类的方式充分使用了语义的规则:

  • 静态的语义规则——》使用到时才进行初始化,实现了懒加载

  • 静态初始化是线程安全,线程的安全由虚拟机内部保证,保证静态初始化时只被初始化一次

以下是kotlin静态内部类的实现方式:

 class SingleD {
     companion object {
         fun getInstance() = InstanceHelper.sSingle
     }
     object InstanceHelper {
         val sSingle = SingleD()
     }
 } 

等价于java的:

 public class SingleD {
     private SingleD() {
 ​
     }
     private static class InstanceHelper {
         static SingleD sInstance = new SingleD();
     }
     public static SingleD getInstance() {
         return InstanceHelper.sInstance;
     }
 } 

优点:

  • 延迟到使用时才进行初始化,提高了类加载的性能

  • 使用静态初始化虚拟机保证线程安全的特性,实现了线程安全且锁的性能在虚拟机内部实现性能较好

缺点:

  • 需要多一个额外的静态内部类来辅助实现


用键盘敲击出的不只是字符,更是一段段生活的剪影、一个个心底的梦想。希望我的文字能像一束光,在您阅读的瞬间,照亮某个角落,带来一丝温暖与共鸣。

版主

站长

具有版权性

请您在转载、复制时注明本文 作者、链接及内容来源信息。 若涉及转载第三方内容,还需一同注明。

具有时效性

目录

欢迎来到青青职场加油站的站点,为您导航全站动态

13 文章数
9 分类数
0 评论数
10标签数
最近评论

访问统计