views:

1148

answers:

5

I would like to know what are ruby's alternatives to the Java methods :

  • wait
  • notify
  • notifyAll

Could you please post a small snippet or some links ?

A: 

I think what you want is Thread#join

threads = []
10.times do
  threads << Thread.new do
    some_method(:foo)
  end
end

threads.each { |thread| thread.join } #or threads.each(&:join)

puts 'Done with all threads'
Squeegy
Not really. Join waits until a thread finishes execution. Wait pauses a thread until it's notified , so that it can resume execution.
Geo
Ah. My bad. I don't actually know Java so my wild guess failed.
Squeegy
+1  A: 

There's no equivalent to notifyAll(), but the other two are Thread.stop (stops the current thread) and run (called on a stopped thread to make it start going again).

Chuck
I believe ConditionVariable#broadcast is equivalent to notifyAll()
finnw
+3  A: 

With the caveat that I don't know Java, based on your comments, I think that you want a condition variable. Google for "Ruby condition variable" comes up with a bunch of useful pages. The first link I get, http://www.linuxtopia.org/online_books/programming_books/ruby_tutorial/Ruby_Threads_and_Processes_Condition_Variables.html, seems to be a nice quick introduction to condition vars in particular, while http://phrogz.net/ProgrammingRuby/tut_threads.html looks like it gives a much broader coverage of threaded programming in Ruby.

womble
It's kinda like Java , except that ruby uses signal and java uses notify. Thanks !
Geo
+1  A: 

I think you're looking for something more like this. It'll work on any object instantiated after this gets executed. It's not perfect, particularly where Thread.stop is outside the mutex. In java, waiting on a thread, releases a monitor.

class Object 
  def wait
    @waiting_threads = [] unless @waiting_threads
    @monitor_mutex = Mutex.new unless @monitor_mutex
    @monitor_mutex.synchronize {
      @waiting_threads << Thread.current
    }
    Thread.stop
  end

  def notify
    if @monitor_mutex and @waiting_threads 
      @monitor_mutex.synchronize {
        @waiting_threads.delete_at(0).run unless @waiting_threads.empty?
      }
    end
  end

  def notify_all
    if @monitor_mutex and @waiting_threads
      @monitor_mutex.synchronize {
        @waiting_threads.each {|thread| thread.run}
        @waiting_threads = []
      }
    end
  end
end
jakrabbit
+1  A: 
What you are looking for is ConditionVariable in Thread.

require "thread"

m = Mutex.new 
c = ConditionVariable.new
t = []

t << Thread.new do
  m.synchronize do
    puts "A - I am in critical region"
    c.wait(m)
    puts "A - Back in critical region"
  end
end

t << Thread.new do
  m.synchronize do
    puts "B - I am critical region now"
    c.signal
    puts "B - I am done with critical region"
  end
end

t.each {|th| th.join }
Sai Venkat