11

I have one java method which contains 5 different internal methods. For performance improvement, I want to call these methods parallely.

e.g. run method1, method2, ... method5 parallel using thread.

private void getInformation() throws SQLException,
            ClassNotFoundException, NamingException {
    method1();
    method2();
    method3();
    method4();
    method5();
}

but all these 5 methods have different business logic.

robjohncox
  • 3,639
  • 3
  • 25
  • 51
user1037452
  • 411
  • 1
  • 7
  • 15

6 Answers6

21

Do something like this:

  1. For each method, create a Callable object that wraps that method.
  2. Create an Executor (a fixed thread pool executor should be fine).
  3. Put all your Callables in a list and invoke them with the Executor.

Here's a simple example:

public void testThread()
{

   //create a callable for each method
   Callable<Void> callable1 = new Callable<Void>()
   {
      @Override
      public Void call() throws Exception
      {
         method1();
         return null;
      }
   };

   Callable<Void> callable2 = new Callable<Void>()
   {
      @Override
      public Void call() throws Exception
      {
         method2();
         return null;
      }
   };

   Callable<Void> callable3 = new Callable<Void>()
   {
      @Override
      public Void call() throws Exception
      {
         method3();
         return null;
      }
   };

   //add to a list
   List<Callable<Void>> taskList = new ArrayList<Callable<Void>>();
   taskList.add(callable1);
   taskList.add(callable2);
   taskList.add(callable3);

   //create a pool executor with 3 threads
   ExecutorService executor = Executors.newFixedThreadPool(3);

   try
   {
      //start the threads and wait for them to finish
      executor.invokeAll(taskList);
   }
   catch (InterruptedException ie)
   {
      //do something if you care about interruption;
   }

}

private void method1()
{
   System.out.println("method1");
}

private void method2()
{
   System.out.println("method2");
}

private void method3()
{
   System.out.println("method3");
}

Make sure each method does not share state (like a common mutable field in the same class) or you may get unexpected results. Oracle provides a good introduction to Java Executors. Also, this book is awesome if you are doing any kind of threading in java.

lreeder
  • 12,047
  • 2
  • 56
  • 65
  • 1
    All is great and all except that nothing past `List> futureList = executor.invokeAll(taskList);` will get executed, so those timers don't work. – Ren Oct 24 '17 at 20:55
  • invoking all methiods parallely but, its creating thread-1 in method1 and thread-2 in method2 and so on. It should create thread-1 for all methods. what we have to do. @Ireeder – Asha Mar 10 '20 at 11:16
  • and shutdown executor, here is possible? – Fernando Pie Sep 30 '21 at 14:48
7

I had similar requirement. On a specific operation, I had to call some set of validator methods which in-turn validates certain components. Every validator used to take certain amount of time and had to reduce it and decided to call it in async.

Indeed there are many ways to achieve it, this is one of the approach which I solved.

Since validators mostly doesn't return any values, took advantage of Runnable class lambda. In below example addition, multiply and subtraction methods will be invoked asynchronously and in parallel.

public class MultiThreading {

        public static void addition() {
            System.out.println("Addition");
        }

        public static void multiply() {
            System.out.println("multiplication");
        }

        public static void subtraction() {
            System.out.println("subtraction");
        }

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

            Runnable callMultiply = () -> multiply();  //Create Runnable reference using lambda
            executor.execute(callMultiply);
            executor.execute(() -> addition()); //inline
            executor.execute(() -> subtraction());
            
            executor.shutdown();
        }
    }
Carl
  • 83
  • 1
  • 5
5

To run method1 in parallel, do following:

Thread t1=new Thread() {
   public void run() {
       method1();
   }
};
t1.start();

Do this for all your methods.

To wait method1 to finish, do

t1.join();

and so for all other threads.

Many people will tell you use threadpool and do not extend Thread - all this has little sense for you just now. Master this way and only then follow that advices.

Alexei Kaigorodov
  • 13,189
  • 1
  • 21
  • 38
  • for all 5 method need to create 5 thread and inside run we need to call them which will make them call parallel ??? – sashikanta Sep 24 '20 at 13:58
0

You can use high level concurrency instrument in Java - thread pool. But anyway you will have to create Runnable objects (tasks) and then use thread pool's method - invokeAll(). Please take a look at Oracle concurrency tutorial

XZen
  • 225
  • 5
  • 27
  • 49
  • but all these 5 methods have different business logic – user1037452 Aug 10 '13 at 14:37
  • @user1037452 So, what's the problem with using thread pool and "different business logic"? I don't fully understand your doubts. But it looks that you need to read some basic information about concurrency stuff in java – XZen Aug 10 '13 at 14:41
0

take a look at java.util.concurrent http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html and the tutorial: http://docs.oracle.com/javase/tutorial/essential/concurrency/ basically, you will have to create an executorserice, some class extending Runnable, and invoke them

jlb
  • 358
  • 3
  • 15
0

You have to use 5 different threads to execute your methods in parallel, the code it's not difficult but pretty boring.

You may want to have a look to Gpars Tasks, which make writing parallel code much more easy and enjoyable.

http://gpars.org/1.0.0/guide/guide/dataflow.html#dataflow_tasks

pditommaso
  • 3,186
  • 6
  • 28
  • 43