You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程下Singleton类ClassA替换ClassB实例的执行逻辑疑问

多线程下单例类替换内部实例的行为疑问

我有一个内部持有另一个类实例的单例类ClassA,代码如下:

@Singleton
class ClassA {

    private var classBInstance: ClassB

    init{
        classBInstance = ClassB()
    }

    fun performOperation(): Result {
        return classBInstance.doSomething()
        // doSomething() takes about 4 seconds
     }

     fun updateClassB() {
       classBInstance = ClassB()
     }
}

ClassA是单例类,被多个线程调用其performOperation()方法。当某个线程调用performOperation()后,内部执行classBInstance.doSomething()(该方法耗时约4秒),此时若另一线程调用updateClassB()将classBInstance替换为新的ClassB实例,我有以下两个疑问:

  1. 正在执行的doSomething()是否会继续用旧的ClassB实例完成全部操作,后续请求才使用新实例?
  2. 替换classBInstance变量后,旧ClassB实例的doSomething()是否会出现问题?

我的期望是:更新classBInstance为新实例时,正在处理的请求仍使用旧实例,只有新请求才使用新实例,特此请教。


问题解答

1. 正在执行的doSomething()会持续使用旧实例

当线程调用performOperation()时,会先读取classBInstance的当前引用(旧实例),之后调用该实例的doSomething()方法。哪怕后续有线程通过updateClassB()替换了classBInstance的引用,已经拿到旧实例引用的线程会继续用这个旧实例完成整个doSomething()的执行流程,只有新发起的performOperation()调用才会读取新的classBInstance引用并使用新实例。

2. 旧实例的doSomething()不会出现异常问题

只要doSomething()方法本身是线程安全的(比如没有未同步的共享可变状态),旧实例的方法执行不会因为classBInstance的引用被替换而受影响。classBInstance变量只是存储了实例的引用,替换引用并不会销毁旧实例——旧实例会一直存在直到没有任何线程持有它的引用(之后会被垃圾回收器回收),在此之前它的方法执行完全不受影响。

注意事项

当前代码中的classBInstance变量没有做线程同步处理,在多线程环境下可能存在可见性问题:比如某个线程更新了classBInstance后,其他线程可能无法立即看到新的引用,导致继续使用旧实例。如果需要确保新实例能被所有线程及时感知,建议给classBInstance添加@Volatile注解(Kotlin),或者通过同步代码块来保证读写操作的可见性与原子性。


内容的提问来源于stack exchange,提问作者Sunny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 00:52:39