Last Updated: February 25, 2016
· davetron5000

A basic multi-threaded processing loop

In JRuby, it's dead simple to launch and manage code to run in a thread, while still having graceful shutdown semantics:

# JRuby only - bring in the java.util.concurrent package
java_import java.util.concurrent

# make a thread pool with 10 threads.  This means
# we can submit any number of blocks of code to run
# but only 10 will run at a time.
service = Executors.new_fixed_thread_pool(10)

# shutdown our ExecutorService when someone kills us
signal.trap('SIGINT') { service.shutdown }

loop do
  work = get_some_work
  service.execute { do_some(work }
  # if someone shut us down, break out of the loop
  break if service.is_shutdown
# at this point, we aren't taking new work, but we 
# might have more work in progress or scheduled.  
# Let's wait a bit for them to finish:

# once we get here, we've either waited 10 seconds, or
# everyone has finished working.  Either way, time to go:

The reasons for using a thread pool via the ExecutorService is to throttle the number of actual threads in flight. Adding threads has a cost, and if we add too many, we lose the benefits gained from a multi-threaded environment. Make sure that instead of using a literal like I did (10), use a configurable value you can easily tweak on production.