Concurrencer: a tool for retrofitting parallelism into sequential Java code

Problem Description

Parallelizing existing sequential programs to run efficiently on multicores is not trivial. The programmer needs to make the program thread-safe (i.e., the program runs correctly when executed from several threads) and also scalable (i.e., the performance of the program improves when adding more parallel resources).

The Java class library has been extended with a package java.util.concurrent (j.u.c.) that provides thread-safe and scalable collections and utility classes. However, manually converting sequential code toward j.u.c. is tedious, error-prone, and omission-prone. This webpage presents our extension to Eclipse's refactoring engine, Concurrencer, which enables a programmer to refactor to j.u.c. utilities. One refactoring converts an int field to an AtomicInteger, which is a lock-free utility for updating integer values. Another refactoring converts a HashMap field to a ConcurrentHashMap, which is a thread-safe, highly scalable implementation for hash maps. Another refactoring converts a recursive divide-and-conquer function into a a function that solves the recursive subproblems in parallel using the ForkJoinTask framework coming in Java 7. Preliminary experience with Concurrencer shows that it refactors code effectively: Concurrencer correctly identifies and applies more transformations than some open-source developers.

Publications

More details about Concurrencer are found in our paper that appears in the Proceedings of International Software Engineering Conference (ICSE'09), Vancouver, May 2009.

Screenshots and Download

Concurrencer is released under the Eclipse Public License. Concurrencer requires that you use Eclipse 3.4, also called the Ganymede distribution (we currently do not support the 64-bit version). Once you have installed Eclipse 3.4, copy this jar file into your Eclipse installation directory, under the plugins directory, then restart Eclipse. To use Concurrencer, you select an int field or a HashMap field from the Java editor by selecting the name of the field. Alternatively, you can select the field to be refactored from the Package Explorer or the Outline View. Invoke the context menu (right-click) on the selected field. Our refactorings are under the "Concurrency Refactorings" menu.

Note: ForkJoinTask framework recently went through some API changes in preparation for the final release. We are currently updating Concurrencer to use the new APIs. Until we are done with the update, you can only use the other two refactorings (Convert Int to AtomicInteger and Convert HashMap to ConcurrentHashMap).

Below is a screenshot from using Concurrencer to Convert an Int field to an AtomicInteger: converting an int field to an AtomicInteger

Below is a screenshot for using Concurrencer to Convert a HashMap field to a ConcurrentHashMap: converting an HashMap field to a ConcurrentHashMap

Below is a screenshot for Converting a recursive sort function into a parallel function that uses the ForkJoinTask framework: parallelizing a recursive sort function by using the ForkJoinTask framework

Feedback

In order to improve Concurrencer we need your feedback. We would love to hear constructive criticism or just learn that you are using Concurrencer. Please contact Danny Dig or John Marrero.