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 ?
I would like to know what are ruby's alternatives to the Java methods :
Could you please post a small snippet or some links ?
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'
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).
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.
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
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 }