Skip to content

Instantly share code, notes, and snippets.

@BrindleFly
Last active December 13, 2015 19:08
Show Gist options
  • Save BrindleFly/4960211 to your computer and use it in GitHub Desktop.
Save BrindleFly/4960211 to your computer and use it in GitHub Desktop.
Java wait/notify/notifyAll for MRI and JRuby
# Old school Java wait/notify
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
# Use Java wait/notify/notifyAll
require "java"
class Object
def wait
create_monitor unless @monitor
@monitor.synchronized {
@monitor.wait
}
end
def notify
create_monitor unless @monitor
@monitor.synchronized {
@monitor.notify
}
end
def notify_all
create_monitor unless @monitor
@monitor.synchronized {
@monitor.notify_all
}
end
protected
def create_monitor
Thread.exclusive {
# If the monitor was created by another thread, just exit
return if @monitor
@monitor = java.lang.Object.new
}
end
end
else
# Implement an equivalent in MRI
class Object
def wait
create_monitor unless @monitor
@monitor.synchronize {
@waiting_threads << Thread.current
}
# Warning: Due to lack of language support in Ruby, the thead stop is outside synchronized block
Thread.stop
end
def notify
create_monitor unless @monitor
if @monitor and @waiting_threads
@monitor.synchronize {
@waiting_threads.delete_at(0).run unless @waiting_threads.empty?
}
end
end
def notify_all
create_monitor unless @monitor
if @monitor and @waiting_threads
@monitor.synchronize {
@waiting_threads.each {|thread| thread.run}
@waiting_threads = []
}
end
end
protected
def create_monitor
Thread.exclusive {
# If the monitor was created by another thread, just exit
return if @monitor
@waiting_threads = [] unless @waiting_threads
@monitor = Mutex.new unless @monitor_mutex
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment