我不具备多线程经验。所以不确定我是否正确使用从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 }
}
}
以下是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;
这是否意味着由于synchronized(this){}
中的空块,代码实际上未同步?
答案 0 :(得分:16)
如果您在不对其进行反编译的情况下查看字节码本身,您将会看到同步发生的情况 - 这是一个剥离了大量加载和存储操作,行号等的版本,但是问题是MONITORENTER
和MONITOREXIT
说明的位置:
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是一项挑战。