我在多线程方面没有太多经验.所以我不确定我是否正确使用了从Kotlin反编译的以下Java代码.

Here is the Kotlin code:

companion object {
    @Volatile private var INSTANCE: SomeDatabase? = null

    fun getInstance(context: Context): SomeDatabase =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
            }
}

以下是Java中的反编译代码:

     SomeDatabase var10000 = ((SomeDatabase.Companion)this).getINSTANCE();
     if (var10000 == null) {
        synchronized(this){}

        SomeDatabase var4;
        try {
           var10000 = SomeDatabase.Companion.getINSTANCE();
           if (var10000 == null) {

               ...

        var10000 = var4;
     }

     return var10000;

这难道不是说,因为百里空挡路,代码实际上是不同步的吗?

推荐答案

If you look at the bytecode itself without decompiling it, you'll see that the synchronization happens as it should - this here is a version stripped of lots of load and store operations, line numbers, etc., but what matters is where the MONITORENTER and MONITOREXIT instructions are:

public final getInstance(Landroid/content/Context;)Lcom/example/SomeDatabase;
    LDC "context"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
    INVOKESTATIC com/example/Foo.access$getINSTANCE$cp ()Lcom/example/SomeDatabase;
    MONITORENTER
    INVOKESTATIC com/example/Foo.access$getINSTANCE$cp ()Lcom/example/SomeDatabase;
    INVOKESTATIC com/example/FooKt.buildDatabase (Landroid/content/Context;)Lcom/example/SomeDatabase;
    INVOKESTATIC com/example/Foo.access$setINSTANCE$cp (Lcom/example/SomeDatabase;)V
    MONITOREXIT
    MONITOREXIT
    ARETURN

您看到的问题不是编译器中的错误,而是反编译器的问题,这并不是特别罕见.将任意生成的字节码反编译回Java是一个相当大的挑战.

Kotlin相关问答推荐

在Kotlin中将String转换为T

在Kotlin中,我是否可以访问已知的WHEN子句值?

如何修改muableStateMapOf的值?

如何使用 Kotlin Maven 更改 Minecraft 插件中的 Shulker GUI 标题

Kotlin:调用 CoroutineScope.launch 与在协程内启动之间的区别

Kotlin 可空泛型

验证构造函数中的值组合

Kotlin 代码是如何编译成原生代码的?

Swift vs Kotlin 在排序数组上的表现

Kotlin 静态函数:伴生对象,@JvmStatic @JvmField

取消信号上的kotlin流量采集

如果 Maybe 完成,则从其他来源将 Maybe 转换为 Single

Kotlin的web-framework框架

如何使用kotlin中的反射查找包中的所有类

如何将vararg转换为list?

Android Jetpack导航,另一个主机片段中的主机片段

Kotlin out-projected 类型禁止使用

如何将 CameraView 与 Jetpack Compose 一起使用?

将 androidx.constraintlayout:constraintlayout lib 更新到 2.0.2 版本后出现崩溃 isRtl () null 引用

Dagger 2 androidx fragment不兼容类型