Kotlin Concurrency: пометить класс как синхронизированный - PullRequest
0 голосов
/ 11 октября 2018

У меня есть класс, который обрабатывает HTTP-запрос.Нет никаких оснований для того, чтобы этот класс когда-либо использовался несколькими потоками, поэтому я хотел бы сделать его полностью синхронизированным.

Причина, по которой я не просто позволяю этому классу быть несинхронизированным, состоит в том, что он содержитмногократное использование вида:

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

    jsonOutput!!.writeTo(PrintWriter(writer))

    // ...
}

Обратите внимание, что я использую оператор !! в нулевой проверке, которая не нужна в Kotlin.Компилятор вынуждает меня добавить его, потому что «jsonOutput является изменяемым свойством, которое могло бы быть изменено к этому времени».

Насколько я понимаю, это означает, что компилятор опасается, что другой поток может изменить значение этого атрибута класса;однако в этом случае данный объект этого класса никогда не будет использоваться более чем одним потоком, поэтому этот вызов оператора не имеет смысла и загромождает код.

Как сделать объект класса доступным изтолько один поток?

Я думал о добавлении @Synchronized для каждого метода, но 1. это звучит громоздко и в отличие от Kotlin, и 2. Я не знаю, посчитает ли компилятор достаточным доказательством того, что этоне может быть изменено.

1 Ответ

0 голосов
/ 11 октября 2018

Насколько я понимаю, это означает, что компилятор опасается, что другой поток может изменить значение этого атрибута класса;однако в этом случае данный объект этого класса никогда не будет использоваться более чем одним потоком, поэтому этот вызов оператора не имеет смысла и загромождает код.

Это не просто другие потоки,но любой вызов метода, который происходит в первой части // ..., потенциально может установить jsonOutput в null.

В любом случае, аннотирование с помощью @Synchronized действительно не поможет, но по той же причине не пометит «маркировку класса как синхронизированного».

Однако правильный способ решения проблемы заключается в следующем:

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

Это получает значение jsonOutput только один раз, поэтому компилятор знает, что оно не null внутриlet.Вы также можете назвать параметр:

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

, который помогает, если у вас есть вложенные нулевые проверки (или просто, если блоки большие).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...