简体   繁体   English

Kotlin并发性:将类标记为已同步

[英]Kotlin Concurrency: mark a class as synchronized

I have a class that handles HTTP request. 我有一个处理HTTP请求的类。 There is no reason for this class to ever be used by multiple threads, so I'd like to make it fully synchronized. 该类没有理由被多个线程使用,因此我想使其完全同步。

The reason I'm not simply letting this class be un-synchronized is because it contains multiple usages of the kind: 我之所以不简单地让该类不同步,是因为它包含该类型的多种用法:

if (jsonOutput != null) {
    // ...

    jsonOutput!!.writeTo(PrintWriter(writer))

    // ...
}

Notice that I'm using the !! 注意,我正在使用!! operator in a null-check, which should not be needed in Kotlin. 空检查中的运算符,在Kotlin中不需要。 The compiler forces me to add it because "jsonOutput is a mutable property that could have been changed by this time". 编译器强迫我添加它,因为“ jsonOutput是一个可变的属性,这次可能已经更改了”。

From my understanding it means the compiler fears an other thread might modify the value of this class attribute ; 以我的理解,这意味着编译器担心其他线程可能会修改此类属性的值。 however in this case a given object of this class will never be used by more than one thread, so this call of the operator is pointless and clutters the code. 但是,在这种情况下,此类的给定对象将永远不会被多个线程使用,因此对运算符的此调用是毫无意义的,并且会使代码混乱。

How can I make the object of the class available from only one thread? 如何仅从一个线程使类的对象可用?

I thought about adding @Synchronized to every method, but 1. that sounds cumbersome and unlike Kotlin, and 2. I don't know if the compiler would consider it enough of a proof that this cannot be modified. 我曾考虑过将@Synchronized添加到每个方法中,但是1.听起来很麻烦,与Kotlin不同,并且2.我不知道编译器是否会认为这足以证明它不能被修改。

From my understanding it means the compiler fears an other thread might modify the value of this class attribute ; 以我的理解,这意味着编译器担心其他线程可能会修改此类属性的值。 however in this case a given object of this class will never be used by more than one thread, so this call of the operator is pointless and clutters the code. 但是,在这种情况下,此类的给定对象将永远不会被多个线程使用,因此对运算符的此调用是毫无意义的,并且会使代码混乱。

It isn't just other threads, but any method call which happens in the first // ... part could potentially set jsonOutput to null . 不只是其他线程,而且在第一// ...部分中发生的任何方法调用都可能jsonOutput设置为null

At any rate, annotating with @Synchronized indeed won't help, but for the same reason neither would "marking a class as synchronized". 无论如何,使用@Synchronized注释确实无济于事,但出于同样的原因,也不会“将类标记为已同步”。

However, the right way to fix the problem is different: 但是,解决问题的正确方法有所不同:

jsonOutput?.let { 
    // ...
    it.writeTo(PrintWriter(writer)) // it refers to jsonOutput value
    // ...
}

This gets jsonOutput 's value just once, so the compiler knows it isn't null inside let . 这得到jsonOutput的价值只有一次,所以编译器知道它不是nulllet You can also name the parameter: 您还可以命名参数:

jsonOutput?.let { jsonOutput ->
    // ...
    jsonOutput.writeTo(PrintWriter(writer))
    // ...
}

which helps if you have nested null checks (or just if the blocks are large). 如果您嵌套了null检查(或者只是块很大),这将很有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM