Я прохожу через Обучение параллельному программированию в Scala и столкнулся с следующим:
В текущих версиях Scala, однако, некоторые коллекции, которые считающиеся неизменяемыми, такие как List и Vector, не могут использоваться совместно синхронизации. Хотя их внешний API не позволяет изменять их, они содержат нефинальные поля.
Совет. Даже если объект кажется неизменным, всегда используйте правильную синхронизацию для обмена любыми объектами между потоками.
От обучения параллельному программированию в Scala от Aleksandar Prokopec, конец главы 2 (стр .58), Packt Publishing, ноябрь 2014 г.
Может ли это быть правильно?
Мое рабочее предположение всегда заключалось в том, что любая внутренняя изменчивость (для реализации лень, кеширования и т.д.) в структурах данных библиотеки Scala, описанных как неизменяемая, была бы идемпотентной, так что худшее, что может случиться в плохом расе, - это работа быть излишне дублированным. Этот автор, кажется, предполагает, что правильность может быть поставлена под угрозу путем одновременного доступа к неизменяемым структурам. Это правда? Нам действительно нужно синхронизировать доступ к спискам?
Значительная часть моего перехода к неизменному стилю была вызвана стремлением избежать синхронизации и потенциальными соперничающими над ними проблемами. Было бы несчастливым серьезным делом узнать, что синхронизацию нельзя отбросить для Scala основных "неизменных" структур данных. Этот автор просто чрезмерно консервативен?
Scala документация коллекций включает в себя следующее:
Коллекция в пакете scala.collection.immutable гарантируется неизменной для всех. Такая коллекция никогда не изменится после ее создания. Поэтому вы можете полагаться на то, что одновременное обращение к одному и тому же набору значений в разные моменты времени всегда даст коллекцию с теми же элементами.
Это не совсем означает, что они безопасны для одновременного доступа несколькими потоками. Кто-нибудь знает об авторитетном утверждении, что они (или нет)?