How to use Callable with void return type?

90,438

Solution 1

You can use java.lang.Thread for parallel execution. However, in most cases it's easier to use an java.util.concurrent.ExecutorService. The latter provides a method to submit a Callable and returns a Future to get the result later (or wait for completion).

If testA.abc() and testB.xyz() should be executed in parallel, you use the ExecutorService to execute the former in a separate thread whereas the latter is executed in the original thread. Then you wait for the completion of the former for synchronization.

ExecutorService executor = ... // e.g. Executors.newFixedThreadPool(4);

Future<Void> future = executor.submit(new Callable<Void>() {
    public Void call() throws Exception {
        testA.abc();
        return null;
    }
});
testB.xyz();
future.get(); // wait for completion of testA.abc()

Solution 2

Why would you need a void for running something in Parallel? For one, if you don't need the return value, you can simply return null.

To make something parallel you need to use threading/scheduling. I would personally recommend avoiding Callables, and using Runnables instead (and hey, no return value).

Solution 3

A shorter version:

ExecutorService executor = ... // e.g. Executors.newFixedThreadPool(4);
Future<?> future = executor.submit(() -> testA.abc());
testB.xyz();
future.get(); // wait for completion of testA.abc()

To be noted that having to run something in parallel with nothing to be returned could be a sign of a bad pattern :)

Also, if you are in a Spring environment, you could use: https://spring.io/guides/gs/async-method/

Share:
90,438
AKIWEB
Author by

AKIWEB

Updated on July 05, 2022

Comments

  • AKIWEB
    AKIWEB almost 2 years

    I am working on a project in which I have multiple interface and two Implementations classes which needs to implement these two interfaces.

    Suppose my first Interface is -

    public Interface interfaceA {
        public void abc() throws Exception;
    }
    

    And its implementation is -

    public class TestA implements interfaceA {
    
    // abc method
    }
    

    I am calling it like this -

    TestA testA = new TestA();
    testA.abc();
    

    Now my second interface is -

    public Interface interfaceB {
        public void xyz() throws Exception;
    }
    

    And its implementation is -

    public class TestB implements interfaceB {
    
    // xyz method   
    }
    

    I am calling it like this -

    TestB testB = new TestB();
    testB.xyz();
    

    Problem Statement:-

    Now my question is - Is there any way, I can execute these two implementation classes in parallel? I don't want to run it in sequential.

    Meaning, I want to run TestA and TestB implementation in parallel? Is this possible to do?

    I was thinking to use Callable here but not sure how to use Callable with void return type here -

    Let's use TestB class as an example:

    public interface interfaceB {
        public void xyz() throws Exception;
    }
    
    public class TestB implements interfaceB, Callable<?>{
    
        @Override
        public void xyz() throws Exception
        {
            //do something
    
        }
    
        @Override
        public void call() throws Exception
        {
            xyz();
        }
    }
    

    Above code gives compilation error..

    UPDATE:-

    It looks like lot of people are suggesting to use Runnable instead of callable. But not sure how do I use Runnable here so that I can execute TestA and TestB in parallel.

  • AKIWEB
    AKIWEB about 10 years
    Thanks for suggestion. Then can you provide me an example how I can execute TestA and TestB in parallel using Runnable instead of callable?
  • nosid
    nosid about 10 years
    ExecutorService is probably the best approach to execute two tasks in parallel. It also supports Runnable. However, Callable has the advantage to also support arbitrary exceptions.
  • IcedDante
    IcedDante over 8 years
    Rogue- what's the problem with using callables in this situation?
  • Rogue
    Rogue over 8 years
    @IcedDante I've always avoided them because of their exception handling, which lead to me having to debug stuff just to find out the exception in a callable is being raised and not printed / thrown out of the context
  • Ali Nadalizadeh
    Ali Nadalizadeh over 5 years
    Very Nice! I did not know we have a Void class to be used there in the template parameter...
  • Basil Bourque
    Basil Bourque about 3 years
  • Rogue
    Rogue about 3 years
    @BasilBourque if you had a list of runnables, then list.forEach(executor::submit); the alternative of wrapping all of those runnables into Callable objects defeats the purpose in terms of the exception handling comments above. That said, Callable doesn't need to be avoided completely, if you have a list of objects that you want to render into Futures accordingly with return values, Callable is appropriate. Just be aware of the exception handling.