9

Not sure if threads safety even applies to ||=.

Was originally reading about ActiveSupport::Memoizable and wondered about thread safety there.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
sent-hil
  • 18,635
  • 16
  • 56
  • 74
  • 1
    Do you mean "Is it a atomic operation?", "Can there be a delay between testing and assignment", then no, I don't see any such guarantee. – j13r Mar 24 '12 at 15:58
  • 5
    An assignment is threadsafe if the variable is in a threadsafe place. So, if you have a global variable then an assignment won't be threadsafe, or, if multiple threads can assign to that variable at the same time. Your question doesn't really make sense. – James Black Mar 24 '12 at 16:13
  • I guess what I meant to ask was would I get into trouble using `||=` with threads? – sent-hil Mar 24 '12 at 16:26

2 Answers2

4

This great post on thread safety concepts in Ruby by Luca Guidi shows that ||= is not thread-safe (at least in MRI).

Community
  • 1
  • 1
Aleksei Chernenkov
  • 991
  • 1
  • 8
  • 23
  • Is this true only only for `@instance` variables? Or could using `||=` still be safe for method variables if no new threads are created within that method? – Kelsey Hannan Jan 10 '18 at 19:29
  • 1
    @KelseyHannan theory to understand is that `||=` is not a atomic operation. its basically act as two operations `a = a || b`. mutations of shared variable by multiple treads can lead to a raise condition. – Oshan Wisumperuma Jun 16 '21 at 12:51
3

It depends on the implementation. Be aware that x ||= y expands to x || x = y, and that x = y is only executed if x is either false or nil.

With that said, the C implementation of the Ruby language should be completely thread safe.

YARV uses native threads in order to implement concurrency, which do run in true parallel. However, in order to maintain backward compatibility, a global, interpreter-wide lock was introduced.

JRuby, however, imposes no internal locking on your code, so you must manually synchronize your calls when needed.

See another answer I've given about the subject for more details. Also, read this excellent answer by Jörg W Mittag for a more in-depth look at the threading models of the various Ruby implementations.

Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
  • 1
    You said "`x = y` is only executed if `x` is *neither* `false` *nor* `nil`" which is incorrect. `x = y` is only executed if `x` is either `false` or `nil`. – Jordan Pickwell Jun 04 '19 at 14:23