Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do singleton classes create problems in a multi-threaded app?

Tags:

ruby

This might be premature optimization, or premature over-cautionization, but I'm avoiding using singletons on a few classes because I'm concerned that down the road I'll need to run my app as multi-threaded, and that the singletons will create conflicts and messiness. Do singletons have this issue in Ruby, or is there some kind of built in namespace so that when an a class refers to the singleton, only the singleton on the same thread is returned?

Edit: to clarify these are observable classes which when updated cause the other classes that are watching them to update. I'm not sure if this is thread safe or not, but I do know that right now I'm passing these observable classes around a ton and it's kind of annoying. And they do seem like natural singleton classes.

like image 505
Jeremy Smith Avatar asked Aug 04 '11 14:08

Jeremy Smith


People also ask

Can we use singleton class in multithreading?

It can be used in a single threaded environment because multiple threads can break singleton property as they can access get instance method simultaneously and create multiple objects.

How can you avoid multithreading conflict issues by using singleton?

Thread Safe Singleton in JavaCreate the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.

What is the disadvantages of using singleton?

Singletons hinder unit testing: A Singleton might cause issues for writing testable code if the object and the methods associated with it are so tightly coupled that it becomes impossible to test without writing a fully-functional class dedicated to the Singleton.


2 Answers

Here is an example of making a singelton threadsafe. You have to treat it like any other object which has state (@things) and is not immutable (readonly). The getters and setters need to access the internal state via a Mutex (mutual exclusion).

require 'singleton'

class MyObject
  include Singleton

  def initialize
    @things = []
    @mutex  = Mutex.new
  end

  def add(thing)
    with_mutex { @things << thing }   
  end

  def things
    with_mutex { @things }
  end

  def clear
    with_mutex { @things.clear }
  end

  def self.add(thing)
    instance.add(thing)
  end

  def self.things
    instance.things
  end

  def self.clear
    instance.clear
  end

  private

  def with_mutex
    @mutex.synchronize { yield }
  end
end

Further reading: http://rubylearning.com/satishtalim/ruby_threads.html

like image 152
Kris Avatar answered Oct 22 '22 13:10

Kris


All classes that aren't written to be thread-safe will cause problems in a multi-threaded environment, regardless of whether they're singletons or not.

The fact that your class is a singleton could make the problem worse, because it's shared by default. You can't have an instance per-thread.

If the singleton state is read-only and immutable you won't have a thread safety issue.

If shared state is modified, you have to ensure that it's thread safe.

like image 30
duffymo Avatar answered Oct 22 '22 13:10

duffymo