Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are Ruby class methods thread-safe?

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.

like image 879
Henley Avatar asked Dec 05 '12 02:12

Henley


People also ask

Are class methods thread-safe?

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.

Is Ruby set thread-safe?

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.

Are Ruby hashes thread-safe?

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.

How do I know if a class is thread-safe?

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.

Is Ruby logger 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.

Are class variables thread-safe?

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.


2 Answers

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.

like image 113
mu is too short Avatar answered Oct 11 '22 20:10

mu is too short


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.

like image 28
Andrew Grimm Avatar answered Oct 11 '22 19:10

Andrew Grimm