Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News New Concurrency Features for Java SE 7

New Concurrency Features for Java SE 7

JSR-166 helped bring Doug Lea's concurrency framework into Java Standard Edition 5. This work carried forward into Java SE 6 as jsr166x, which added a number of features to the Java collections framework for concurrency.

Although the contents of Java SE 7 are still in flux, early candidates for inclusion are are already taking shape in jsr166y: a fork/join framework and a transfer queue. InfoQ spoke with Doug Lea about these features and concurrency in Java SE 7.

The fork/join framework is a "multicore-friendly lightweight parallel framework" that supports a style of parallel programming where problems are recursively split into smaller fragments, solved in parallel and recombined, as described in this pseudocode from A Java Fork/Join Framework:

Result solve(Problem problem) {
if (problem is small)
directly solve problem
else {
split problem into independent parts
fork new subtasks to solve each part
join all subtasks
compose result from subresults

This ensures that the work can be accomplished in parallel and works well on multi-core systems:

Big (32+) multicores will be coming out in volume during the lifetime of Java 7, and having this framework in place will allow people running them to get relatively simple speedups for computation-intensive tasks. Right now, forkjoin works best on machines like Sun Niagaras and Azuls, which are the only current processors of the form that will soon be common. It also works well on standard SMPs. In general, you don't get many speedup benefits with less than 4 processors though -- the main targets are in the dozens to hundreds of processors range.

Given a sufficiently-decomposed task size, the cost of executing the task may be exceeded by the cost of creating a thread. Accordingly, the fork/join framework uses thread pools which can be sized appropriately to the number of available cores to reduce the swapping overhead. To avoid straggling threads, the framework includes a work-stealing approach where a thread with no work can poach queued work from a slower-executing thread. The A Java Fork/Join Framework paper describes the mechanisms used by the fork/join framework and shows examples of performance in multicore systems and comparisons to other similiar kinds of parallel programming frameworks.

Describing the likely usage scenarios and adoption for the fork/join framework, Doug Lea said:

Overall, I expect an adoption curve vaguely similar to other concurrency utilities. At first only a few people who really need them will use them, but eventually, it will be hard to find programs that don't somehow rely on them, often buried deep inside infrastructure components. For this reason, surface syntax support might not be all that important anyway -- the kinds of library/component developers most likely to want to incorporate them are more likely to put up with awkward usage.

Ideally, there will be several layers of usages:

  1. "Do this stuff in parallel" level, where a language or tools translates into parallel-ese, while also checking for safety/liveness. This is still partially in the realm of research though.

  2. Arranging for parallel operations on collections. -- map, reduce, apply, etc. Programmers who can think about manipulating collections using aggregate all-at-once operations can use these to speed up common kinds of processing. (This is the ListTasks, ArrayTasks, etc layer.)

  3. Hand-crafting an efficient forkjoin solution for a given problem. This is the layer I'm right now concentrating on, to be sure we can support the wide range of parallel algorithms possible using work-stealing frameworks. (Some of the currently odd-looking and under-explained methods like isQuiescent are designed for such advanced usages. Most programs just use "fork" and "join", but the others are there when you need them.)

  4. Extending the framework to create new kinds of ForkJoinTasks etc. For example, those that operate transactionally. Only a very small number of people (for example, perhaps the Fortress runtime library developers) will ever need to do this, but there need to be enough base extension hooks to pull this off.

Another candidate for Java SE 7 is the TransferQueue. TransferQueue extends the BlockingQueue interface by adding producer-side blocking where the producer transfers an object to the consumer when both are ready. Non-blocking and timeout-style transfers are also available.
This is suitable for some kinds of message-passing applications where a hand-off can be necessary, and "to create a simpler-to-use thread pool, in which sometimes tasks must be synchronously transfered"

The transfer queue and fork/join framework may not be the only concurrency features added to Java SE 7. According to Doug Lea, there is an ongoing wishlist of new and request-for-enhancement features, including scalable counters, a ConcurrentIdentityHashMap, "additions to the atomics package to better support expert-mode fine-tuning of memory model effects" and algorithmic improvements to java.util.Collections.

The jsr166y effort builds on the work done in Java SE 6 as jsr166x, which brought new collections into Java SE6: Deque, BlockingDeque, NavigableSet, NavigableMap and ConcurrentNavigableMap (as well as the implementing classes, ArrayDeque, LinkedBlockingDeque, ConcurrentSkipListSet, ConcurrentSkipListMap and enhancements to TreeMap).

For more information on JSR-166, jsr166x and jsr166y, visit the Concurrency Interest site. InfoQ will keep you up to date as Java SE 7 progresses.

Rate this Article