For instance, methods such as:
class MyClass
self.perform(id)
hash = doSomething(id)
doMoreStuff(hash)
return hash
end
end
My concern is if I have multiple threads calling MyClass.perform()
. Could the object hash
be potentially overwritten by another thread? In other words, Thread 1 calls doSomething
and gets a hash returned of {1 => 1}
. But right afterwards Thread 2 calls doSomething
and gets a hash of {2 => 2}
. What happens now? Does Thread 1's hash change to {2 => 2}
?
Or does each thread work on its own hash
that can never be touched by other threads? Assume doSomething
and doMoreStuff
are already thread-safe.
If it matters, I am using Rails 3.0.
Whether a method is thread safe or not depends on what the method does. Working with local variables only is thread safe. But when you change the same non local variable from different threads, it becomes unsafe.
None of the core data structures (except for Queue) in Ruby are thread-safe. The structures are mutable, and when shared between threads, there are no guarantees the threads won't overwrite each others' changes. Fortunately, this is rarely the case in Rails apps.
No, you cannot rely on Hashes being thread safe, because they aren't built to be thread safe, most probably for performance reasons. In order to overcome these limitations of the standard library, Gems have been created which provide thread safe (thread_safe) or immutable (hamster) data structures.
For a standard Java SE class, the best way to know whether or not the class is thread-safe is to carefully read its documentation. Always read both the class documentation and the method documentation. If either say it's not synchronized or not thread-safe, you know it's not thread-safe.
Yes, but even though only one thread runs at a time that doesn't make multi-threaded Ruby code thread-safe as what should be atomic operations can span multiple statements.
Given the structure of the JVM, local variables, method parameters, and return values are inherently "thread-safe." But instance variables and class variables will only be thread-safe if you design your class appropriately.
The local variables, such as your hash
, are local to the particular invocation of the surrounding method. If two threads end up calling perform
at the same time, then each call will get its own execution context and those won't overlap unless there are shared resources involved: instance variables (@hash
), class variables (@@hash
), globals ($hash
), ... can cause concurrency problems. There's nothing to worry about thread-wise with something simple like your perform
.
However, if perform
was creating threads and you ended up with closures inside perform
, then you could end up with several threads referencing the same local variables captured through the closures. So you do have to be careful about scope issues when you create threads but you don't have to worry about it when dealing with simple methods that only work with local variables.
Something being a "class method" (which is just a singleton method on a class object) doesn't make it any more thread-safe than it being an instance method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With