Java & Multicore

Recently I needed to run some very CPU intensive calculations in Java. In order to harvest the full power of my multicore machine I took a look at Java’s concurrent package. I never used this package before. Either I had some convenient third party library functions at my hand which successfully were able to hide all the multithreading stuff from me, sometimes I struggled with Thread, Runnable and synchronized statements or … I just used another language :P

So here are my results from a short trip into the adventurous realm of multicore programming in Java. To make things a little bit simpler in this post I will demonstrate to run several functions calculating a high Fibonacci number instead of using a more complicated real world example. The calculations will be distributed via a thread pool and all classes used in this example belong to the Java standard library, so there won’t be a need to install any extra packages.

The first thing we will need is a class implementing the java.util.concurrent.Callable interface in which fib(int n) will be a static function returning an integer:

class FibTask implements Callable<Integer> {
  private int n;
  public FibTask(int n) {
    this.n = n;
  }

  @Override
  public Integer call() throws Exception {
    return fib(this.n);
  }
}

Before we start to build our thread pool we can retrieve the amount of CPUs/cores of our system from the Java runtime:

int cpus = Runtime.getRuntime().availableProcessors();

OK, so the next step is building a thread pool. If you are looking for a pool with specific parameters and behaviour you can build one by using the ThreadPoolExecutor class. But luckily the concurrent package already offers a nice short cut to create a pool with a fixed size:

ExecutorService pool = Executors.newFixedThreadPool(cpus);

To execute functions in the pool you can either use it’s execute method or even more convenient: invokeAll. This method takes a list of tasks which have to implement the Callable interface executes them and returns a list of Future objects which hold the results of the Callable objects. The cool thing about invokeAll is it makes sure all tasks are executed before returning anything. So for all elements in the returned list Future.isDone() will be true:

List<FibTask> tasks = new ArrayList<FibTask>();			
for (int i = 0; i < cpus; i++) {
  tasks.add(new FibTask(45));
}			
List<Future<Integer>> results = pool.invokeAll(tasks);

The results list holds the Future values now. If the pool is no longer needed, it should be closed properly by calling it’s shutdown() method. Before we can retrieve and print out the results we need to check for any errors occurred during the calculation:

for (Future<Integer> result : results) {
  if (result.isCancelled()) {
    System.err.println("Life is a bitch");
  } else {
    try {
      System.out.println("result: " + result.get());
    } catch (ExecutionException e) {
      System.out.println(e.getCause());
    }
  }
}

And this is all you need to run your code on multiple cores. Couldn’t be easier!

Advertisements

0 Responses to “Java & Multicore”



  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s





%d bloggers like this: