Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

Java Callable Example

farenda 2015-10-19 0

Problem:

How to use Java Callable to run tasks that actually return results? In this post we’ll show how to use ExecutorService to run tasks in separate threads to compute and return results.

Solution:

In the following example we’re going to use another feature from fantastic java.util.concurrent package: Callable<T>. The interface is a sister of Runnable, which you could see in action in our previous posts (Java Runnable, Java ExecutorService, and others). There are a couple of differences between them:

  1. Callable<T> returns a Future<T> that will return a result… in the future. :-)
  2. Callable<T> is parametrized with result’s type.
  3. Callable’s method is called call() and may throw an Exception.

To perform our computation we’re going to use ExecutorService‘s. The method for Callables is <T> Future<T> submit(Callable<T>), which just submits given task to the executor for execution in a thread, and returns an object (Future<T>), which will have a result of computation when it’s finished.

Enough talking, here’s the code:

package com.farenda.java.util.concurrent;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

public class CallableExample {

    private static class ComputingTask implements Callable<Integer> {

        private static int nth = 0;
        private final int id = ++nth;

        @Override
        public Integer call() throws Exception {
            int value = new Random().nextInt(1000);
            try {
                System.out.printf("Task %d started computing...%n", id);
                MILLISECONDS.sleep(value);
            } catch (InterruptedException e) {
                // ignore interruptions
            }
            System.out.printf("Task %d is returning value: %d%n",
                    id, value);
            return value;
        }
    }

    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();

        System.out.println("Submitting tasks for execution:");
        List<Future<Integer>> results = new LinkedList<>();
        for (int i = 0; i < 5; ++i) {
            results.add(executor.submit(new ComputingTask()));
        }

        System.out.println("Getting results from futures:");
        for (Future<Integer> result : results) {
            try {
                System.out.printf("computed result: %d%n", result.get());
            } catch (InterruptedException e) {
                System.out.println("Interrupted while waiting for result: "
                        + e.getMessage());
            } catch (ExecutionException e) {
                System.out.println("A task ended up with an exception: "
                        + e.getCause());
            }
        }

        System.out.println("Shutting down the executor.");
        executor.shutdown();
    }
}

As you can see the code is straightforward. We’re creating task, submit them to the executor and collect futures. Later we’re going through futures to get results. To do that we’re using get() method, which blocks and waits for the result. If you don’t want to wait indefinitely long, you can use get(long timeout, TimeUnit unit) that allows to wait only for specified time. There’s also another useful method – isDone(). It allows to check without blocking whether a future already has a result.

Here’s the result of running the above code:

Submitting tasks for execution:
Getting results from futures:
Task 2 started computing...
Task 1 started computing...
Task 4 started computing...
Task 5 started computing...
Task 3 started computing...
Task 5 is returning value: 85
Task 1 is returning value: 117
computed result: 117
Task 3 is returning value: 165
Task 4 is returning value: 405
Task 2 is returning value: 603
computed result: 603
computed result: 165
computed result: 405
computed result: 85
Shutting down the executor.

Nice and useful feature. Stay tuned for more posts about Java Concurrency.

Share with the World!
Categories Java Tags java, java-concurrency
Previous: Java ThreadFactory
Next: Java AutoCloseable ExecutorService

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2021

sponsored
We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.Ok