4

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 String 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 String 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?

AKIWEB
  • 19,008
  • 67
  • 180
  • 294

4 Answers4

8

Sure it is possible. You have actually many options. Preferred one is using callable and executors.

    final ExecutorService executorService = Executors.newFixedThreadPool(2);
    final ArrayList<Callable<String>> tasks = Lists.newArrayList(
            new Callable<String>()
            {
                @Override
                public String call() throws Exception
                {
                    return testA.abc();
                }
            },
            new Callable<String>()
            {
                @Override
                public String call() throws Exception
                {
                    return testB.xyz();
                }
            }
    );

    executorService.invokeAll(tasks);

This method gives you opportunity to get a result from executions of your tasks. InvokeAll returns a list of Future objects.

    final List<Future<String>> futures = executorService.invokeAll(tasks);
    for (Future<String> future : futures)
    {
        final String resultOfTask = future.get();
        System.out.println(resultOfTask);
    }

You can make your code easier to use if you make your classes implements Callable, then you will reduce amount of code needed to prepare list of tasks. Let's use TestB class as an example:

public interface interfaceB {
    String xyz() throws Exception;
}

public class TestB implements interfaceB, Callable<String>{

    @Override
    public String xyz() throws Exception
    {
        //do something
        return "xyz"; 
    }

    @Override
    public String call() throws Exception
    {
        return xyz();
    }
}

Then you will need just

Lists.newArrayList(new TestB(), new TestA());

instead of

final ArrayList<Callable<String>> tasks = Lists.newArrayList(
            new Callable<String>()
            {
                @Override
                public String call() throws Exception
                {
                    return testA.abc();
                }
            },
            new Callable<String>()
            {
                @Override
                public String call() throws Exception
                {
                    return testB.xyz();
                }
            }
    );

Whats more, executors gives you power to maintain and reuse Thread objects which is good from performance and maintainability perspective.

enterbios
  • 1,725
  • 12
  • 13
  • Thank You. Suppose if I have 30 such implementation classes, then I need to do this 30 times in a separate call method. I guess not? I can still re-use some of the threads I guess? – AKIWEB Mar 31 '14 at 06:59
  • ExecutorService will reuse threads of course (depending on strategy you choose). – enterbios Mar 31 '14 at 07:02
  • Thanks a lot. Can you provide an example on this - `You can make your code easier to use if you make your classes implements Callable` if possible basis on my code scenario? It will be of great help. – AKIWEB Mar 31 '14 at 07:08
  • Thanks a lot. So if I call this `Lists.newArrayList(new TestB(), new TestA());` then it will automatically make a call to each `call` method respectively in parallel? I guess I still need to use ExecutorsService for this.. Right? – AKIWEB Mar 31 '14 at 07:19
  • Hehe, yes you still need to use ExecutorService, it will just reduce amount of code required to create your tasks. ExecutorService gives you more flexibility of maintaining execution of your tasks, like providing timeouts, or using different thread management strategy like CachedThreadPool for example. – enterbios Mar 31 '14 at 07:32
  • Yeah make sense now. But quick question - In my example, `abc` and `xyz` method have void return type instead of String. Then In that scenario how Callable and call will look like as you have shown in your second suggestion. – AKIWEB Apr 01 '14 at 04:15
  • Use 'Runnable' instead of 'Callable' if you are not interested in the result of task executed by thread. – Braj Jun 03 '16 at 06:30
1

Create Two Thread and run two implementation parallely. Code snippet -

ThreadA{

  public void run(){
      TestA testA = new TestA();
      testA.abc();
  }
}

...

ThreadB{

  public void run(){
      TestB testB = new TestB();
      testB.xyz();
  }
}

Start this two thread from main method -

public static void main(String[] args){
    new ThreadA().start();
    new ThreadB().start();
}
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
1

Try this one

Collect all the classes of same interface and call them in Multi threading.

Use Callback mechanism to get the result back

import java.util.ArrayList;
import java.util.List;

public class Demo123 {
    public static void main(String[] args) {

        List<InterfaceA> a = new ArrayList<InterfaceA>();
        List<InterfaceB> b = new ArrayList<InterfaceB>();

        TestA testA = new TestA();
        TestB testB = new TestB();

        a.add(testA);
        b.add(testB);

        for (final InterfaceA i : a) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        i.callback(i.abc());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

        for (final InterfaceB i : b) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        i.callback(i.xyz());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

    }
}

interface MyCallback {
    public void callback(String value);
}

interface InterfaceA extends MyCallback {
    public String abc() throws Exception;
}

class TestA implements InterfaceA {

    @Override
    public String abc() throws Exception {
        return "abc";
    }

    @Override
    public void callback(String value) {
        System.out.println("value returned:" + value);
    }
}

interface InterfaceB extends MyCallback {
    public String xyz() throws Exception;
}

class TestB implements InterfaceB {

    @Override
    public String xyz() throws Exception {
        return "xyz";
    }

    @Override
    public void callback(String value) {
        System.out.println("value returned:" + value);
    }
}
Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
0

You may try it like this:

public static void main(String[] args) throws InterruptedException {
    Executors.newCachedThreadPool().invokeAll(Arrays.asList(
        new Callable<String>() {
            @Override public String call() { return new TestA().abc(); }
        },
        new Callable<String>() {
            @Override public String call() { return new TestB().xyz(); }
        }));
}

public interface InterfaceA {
    public String abc() throws Exception;
}

public interface InterfaceB {
    public String xyz() throws Exception;
}

class TestA implements InterfaceA {
    @Override public String abc() {
        System.out.println("Inside A"); return null;
    }
}

class TestB implements InterfaceB {

    @Override public String xyz() {
        System.out.println("Inside B"); return null;
    }
}
Harmlezz
  • 7,972
  • 27
  • 35