Строка get/set threadsafe?

Скажем, у меня есть следующее:

public class Foo{
    private String bar;

    public String getBar(){
        return bar;
    }

    public void setBar(String bar){
        this.bar = bar;
    }
}

Являются ли эти методы автоматически потокобезопасными из-за неизменяемости класса String или требуется какой-то механизм блокировки?

7
nl ja de
@ TheodorosChatzigiannakis, Да, моя ошибка! Исправлена.
добавлено автор mre, источник
Я предполагаю, что вы имеете в виду String в настройщике.
добавлено автор Theodoros Chatzigiannakis, источник
Связанный вопрос c #: stackoverflow.com/questions/ 3595114/& hellip;
добавлено автор PermGenError, источник
Объект String - это не конечная ссылка на него. Подробнее см. stackoverflow.com/a/6060405/1812922 .
добавлено автор alldayremix, источник

4 ответы

Нет, это не потокобезопасно. Foo изменен, поэтому, если вы хотите, чтобы разные потоки отображали одно и то же значение bar - то есть согласованность - либо:

  • Make bar volatile, or
  • Make the methods synchronized, or
  • Use an AtomicReference.

Чтение и запись строки bar сами по себе являются атомарными, но атомарность не является безопасностью потоков.

http://docs.oracle.com/javase/tutorial/essential/concurrency /atomic.html


Для углубленного охвата параллелизма Java возьмите копию Java Concurrency in Practice (aka JCIP) </а>.

18
добавлено
@Matt Ball, если вместо этого поле String было изменено, тогда volatile не делал класс потоком безопасным?
добавлено автор gstackoverflow, источник
@ Clockwork-Muse и какое состояние гонки было бы? TBH, такие вопросы, почему я избегаю совместного использования изменяемых (неконкурентных-библиотечных) объектов по потокам как можно больше.
добавлено автор Matt Ball, источник
+1 Или просто объявить bar как final , так что ссылка не может быть повторно назначена другому значению. Конечно, тогда не будет сеттера :)
добавлено автор Eng.Fouad, источник
Это непреложно. В этом случае нет необходимости в сеттере. И вы должны обязательно указывать конструктор для инициализации значения, потому что вы не можете его изменить, как только вы выйдете из конструктора в этом случае.
добавлено автор duffymo, источник
... Из любопытства, действительно ли это имеет значение? Я имею в виду, что если ваша фактическая проблема - это состояние гонки, это может произойти, несмотря на volatile или synchronized - он просто уменьшает «окно», в котором это может произойти, правильно? Или я чего-то не хватает?
добавлено автор Clockwork-Muse, источник
Thread one постоянно обновляет строку bar . Thread two ожидает, что bar читается как некоторое значение (просто вращающийся с циклом while (...) , скажем). Условие гонки - для потока два, чтобы прочитать значение bar , прежде чем поток один обновит его снова. Хотя любой из этих опций делает так, чтобы у всех потоков была одинаковая внутренняя ссылка (хотя ссылки являются атомарными независимо от ), это не имеет значения, если они работают над объектом в разное время -slices. И да, вот так я предпочитаю неизменные объекты.
добавлено автор Clockwork-Muse, источник

Вы устанавливаете ссылки, и поэтому неизменность String не входит в игру. Вы не влияете на содержимое String .

7
добавлено

Нет, небезопасно.

Это изменчивое поведение Foo; Непрерывность String не начисляется Foo.

public class Foo{
    private String bar;

    public synchronized String getBar(){
        return bar;
    }

    public synchronized void setBar(String bar){
        this.bar = bar;
    }
}
4
добавлено
@duffymo делает несинхронизированный геттер с синхронизированной сеттерной гарантией согласованности по потокам?
добавлено автор Matt Ball, источник
@MattBall Очевидно, что нет.
добавлено автор assylias, источник
+1 Как насчет синхронизации getBar() ? Может быть, какой-то поток устанавливает новое значение в bar , а другие потоки читают bar .
добавлено автор Eng.Fouad, источник
@duffymo, поскольку у вас есть это сейчас, геттер должен быть синхронизирован, чтобы обеспечить текущее состояние bar для всех потоков
добавлено автор Steve Kuo, источник
Извините, для меня это не имеет смысла. Я думаю, что ваши комментарии только путают проблему.
добавлено автор duffymo, источник
-1 Это просто странно.
добавлено автор Tom Hawtin - tackline, источник

Нет, это не потокобезопасно.

Хотя String неизменен, проблема возникает из поля Foo . Чтобы сделать это более очевидным, рассмотрите, например, метод, задачей которого было бы append (а не заменить) значение bar . Когда он вызывается из нескольких потоков, некоторые записи могут быть потеряны. То же самое (потерянная запись) может случиться и с вашим простым сеттером, даже если в этом случае это не очевидно.

3
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async