Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable callables with different return types

The problem I have in hand is that I methods one(), two(), three(), four() that have a different return types say, A, B, C, D and I need to spawn variable numbers of threads (one for each method depending on the use case. This means I would want to call a subset of methods at a time.) Now, am using the cachedThreadPool to submit these callables. Some code below:

public class Dispatcher {

  public void dispatch(List<MethodNames> methodNames) {
    //Now I am going to iterate through the list of methodNames
    //And submit each method to the `ExecutorService`
    for(MethodNames m : methodNames) {
      switch(m) {
        case ONE: //submit one()
                  //wait and get the future
                  Future<A> future = cachePool.submit(new Callable<A>() {
                    @Override
                    public A call() {
                      return one();
                    });
                  A response = future.get(); 
             break;
        ....
      }
    }
  }
}

public enum MethodNames {
  ONE, TWO, THREE, FOUR
}

//Example methods:
public A one() {
}

public B two() {
}

My question is how do the above such that all the method calls are made without having to wait for one to finish. Also, how do I gather all the futures and wait for them to finish cause all the futures have a different generic type Future<A>, Future<B> etc. I make the call to submit() inside the case statement so I don't have the access to the returned Future<T> outside the case. Now I could do an if, else instead of the for loop but I am trying to figure out if there is a better way to achieve this.

like image 796
noMAD Avatar asked May 05 '26 05:05

noMAD


1 Answers

I would do it this way -

  • Create an interface, let's say I.
  • Have classes A, B, C and D implements I.
  • Use enums valueOf and object overriding to remove case statement.
  • Use polymorphism and return I from all the methods.
  • Below is the code (not including A, B, C, D, I) as they are plain class and interface - not doing much.

Below is the code:

Dispatcher.java

package com.test.thread;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

public class Dispatcher {

public void dispatch() throws InterruptedException, ExecutionException {
    Map<MethodNames, Future<I>> reponse = new HashMap<MethodNames, Future<I>>();
    ExecutorService cachePool = Executors.newCachedThreadPool();
    for (MethodNames methodNames : MethodNames.values()) {
        Future<I> future = cachePool.submit(methodNames.worker());
        reponse.put(methodNames, future);
    }
    cachePool.awaitTermination(5, TimeUnit.MINUTES);
    for(MethodNames key : reponse.keySet()) {
        I result = reponse.get(key).get();
        System.out.println("result :: " + result);
    }
}

public static void main(String[] args) throws InterruptedException, ExecutionException {
    new Dispatcher().dispatch();
}

}

MethodNames.java

package com.test.thread;

import java.util.concurrent.*;

public enum MethodNames {
ONE {
    @Override
    public Callable<I> worker() {
        return new Callable<I>() {
            @Override
            public I call() throws InterruptedException {
                System.out.println("Thread1");
                TimeUnit.SECONDS.sleep(30);
              return new A();
            }};
    }
},
TWO {
    @Override
    public Callable<I> worker() throws InterruptedException {
        return new Callable<I>() {
            @Override
            public I call() throws InterruptedException {
                System.out.println("Thread2");
                TimeUnit.SECONDS.sleep(30);
              return new B();
            }};
    }
},
THREE {
    @Override
    public Callable<I> worker() throws InterruptedException {
        return new Callable<I>() {
            @Override
            public I call() throws InterruptedException {
                System.out.println("Thread3");
                TimeUnit.SECONDS.sleep(30);
              return new C();
            }};
    }
},
FOUR {
    @Override
    public Callable<I> worker() throws InterruptedException {
        return new Callable<I>() {
            @Override
            public I call() throws InterruptedException {
                System.out.println("Thread");
                TimeUnit.SECONDS.sleep(30);
              return new D();
            }};
    }
};
public abstract Callable<I> worker() throws InterruptedException;

}

like image 165
TheCodingFrog Avatar answered May 08 '26 09:05

TheCodingFrog



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!