这是Kotlin的一个错误还是我错过了什么?

ore*_*reh 13 multithreading kotlin

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

这是Kotlin代码:

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

    fun getInstance(context: Context): SomeDatabase =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
            }
}
Run Code Online (Sandbox Code Playgroud)

这是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;
Run Code Online (Sandbox Code Playgroud)

这是不是意味着代码实际上没有同步,因为空块synchronized(this){}

zsm*_*b13 16

如果您在不对其进行反编译的情况下查看字节码本身,您将看到同步发生应该 - 这是一个剥离了大量的加载和存储操作,行号等的版本,但重要的是它MONITORENTERMONITOREXIT说明是:

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
Run Code Online (Sandbox Code Playgroud)

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