ruby thread programming , ruby equivalent of java

2019-04-28 16:41发布

问题:

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 ?

回答1:

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, seems to be a nice quick introduction to condition vars in particular, while this looks like it gives a much broader coverage of threaded programming in Ruby.



回答2:

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 }


回答3:

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).



回答4:

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


回答5:

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'