Posted by iconaraon November 23, 2012
Java has lots of powerful concurrency features, something that Ruby lacks. With JRuby it's easy to use java.util.concurrent to make multithreading (relatively) easy.
The most important piece of the java.util.concurrent package, or j.u.c as it’s sometimes called, is executors. Think of an executor as a thread pool that executes your tasks, taking care of the nitty-gritty details for you.
Here’s how to create an executor service with four threads and run some calculations:
module JavaConcurrent
include_package 'java.util.concurrent'
end
executor = JavaConcurrent::Executors.new_fixed_thread_pool(4)
100.times do |n|
executor.execute do
calculate_something(n)
end
end
Notice how the call to #execute took a block. This is JRuby making your life easy. The method takes a java.lang.Runnable in Java, but JRuby takes care of wrapping your block in a proxy object that implements that interface, and calls your block when the Java code calls any of the methods of the interface (in this case there’s only one method: run).
If you run the code above your script will not exit. The reason for that is that the executor and its threads are still around, waiting for more work. You need to call #shutdown on the executor:
executor.shutdown
#shutdown will not force the threads to quit, and it will actually not do anything immediately, what it will do is gracefully shut down once all tasks have completed. There are ways to forcefully shut down all threads too, but you should probably read the documentation before you try them.
You can read more about the j.u.c package in the Javadocs, and there’s also a great book on Java concurrency called “Java Concurrency in Practice”. The j.u.c package contains lots of other useful things like concurrent collections, locks, and coordination mechanisms, and the Executors factory lets you create all sorts of thread pools for different purposes.
