简体   繁体   中英

Kotlin Concurrency: mark a class as synchronized

I have a class that handles HTTP request. 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. The compiler forces me to add it because "jsonOutput is a mutable property that could have been changed by this time".

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.

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 .

At any rate, annotating with @Synchronized indeed won't help, but for the same reason neither would "marking a class as 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 . 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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