Это в методе экземпляра, не путать с методом класса.answers
метод для экземпляра из User
, а не для самого класса User
.Этот метод кэширует ответы в экземпляре User
, но пока этот экземпляр User
создается при каждом веб-запросе (например, User.find()
или User.find_by()
), все в порядке, потому чтоЭкземпляр не живет между потоками.Обычной практикой является поиск записей каждого веб-запроса в контроллере, так что вы, вероятно, делаете это.
Если этот метод был непосредственно для класса User
(например, User.answers
), то вы 'Мне нужно оценить, безопасно ли сохранять это кэшированное значение в потоках и веб-запросах.
Напомним, что единственная забота о безопасности потоков - это методы класса, переменные класса (переменные экземпляра, которые используют два в знаке)такие как @@answers
), и методы экземпляра, где экземпляр живет после одного веб-запроса.
Если вам когда-нибудь понадобится безопасно использовать переменную уровня класса, вы можете использовать Thread.current
, которыйпо сути является хешем для каждого потока (например, {}), в котором вы можете хранить значения. Например, Thread.current[:foo] = 1
будет примером.ActiveSupport использует это при настройке Time.zone
.
В качестве альтернативы вы можете найти моменты, когда вам нужен отдельный массив, который вам нужно безопасно разделить между потоками, и в этом случае вам нужно будет просмотреть Mutex
, чтов основном позволяет вам иметь массив, который вы блокируете и разблокируете, чтобы обеспечить потокам безопасный доступ к чтению и записи в нем.Например, в Sidekiq для управления рабочими используется Mutex.Вы блокируете Mutex, чтобы никто другой не мог его изменить, затем пишете в него, а затем разблокируете его.Важно отметить, что если какой-либо другой поток захочет записать в Mutex, пока он заблокирован, ему придется подождать, пока он разблокируется (например, поток просто делает паузу, пока другой поток пишет), поэтому важно заблокировать какКороче как можно.